summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bullet/SCsub191
-rw-r--r--modules/bullet/SCsub_with_lib33
-rw-r--r--modules/bullet/area_bullet.cpp284
-rw-r--r--modules/bullet/area_bullet.h169
-rw-r--r--modules/bullet/btRayShape.cpp94
-rw-r--r--modules/bullet/btRayShape.h87
-rw-r--r--modules/bullet/bullet_physics_server.cpp1364
-rw-r--r--modules/bullet/bullet_physics_server.h362
-rw-r--r--modules/bullet/bullet_types_converter.cpp94
-rw-r--r--modules/bullet/bullet_types_converter.h57
-rw-r--r--modules/bullet/bullet_utilities.h44
-rw-r--r--modules/bullet/collision_object_bullet.cpp320
-rw-r--r--modules/bullet/collision_object_bullet.h234
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp111
-rw-r--r--modules/bullet/cone_twist_joint_bullet.h58
-rw-r--r--modules/bullet/config.py6
-rw-r--r--modules/bullet/constraint_bullet.cpp50
-rw-r--r--modules/bullet/constraint_bullet.h64
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp241
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.h65
-rw-r--r--modules/bullet/godot_collision_configuration.cpp91
-rw-r--r--modules/bullet/godot_collision_configuration.h50
-rw-r--r--modules/bullet/godot_collision_dispatcher.cpp54
-rw-r--r--modules/bullet/godot_collision_dispatcher.h48
-rw-r--r--modules/bullet/godot_motion_state.h96
-rw-r--r--modules/bullet/godot_ray_world_algorithm.cpp104
-rw-r--r--modules/bullet/godot_ray_world_algorithm.h83
-rw-r--r--modules/bullet/godot_result_callbacks.cpp244
-rw-r--r--modules/bullet/godot_result_callbacks.h152
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp163
-rw-r--r--modules/bullet/hinge_joint_bullet.h54
-rw-r--r--modules/bullet/joint_bullet.cpp38
-rw-r--r--modules/bullet/joint_bullet.h49
-rw-r--r--modules/bullet/pin_joint_bullet.cpp112
-rw-r--r--modules/bullet/pin_joint_bullet.h57
-rw-r--r--modules/bullet/register_types.cpp47
-rw-r--r--modules/bullet/register_types.h37
-rw-r--r--modules/bullet/rid_bullet.h50
-rw-r--r--modules/bullet/rigid_body_bullet.cpp999
-rw-r--r--modules/bullet/rigid_body_bullet.h302
-rw-r--r--modules/bullet/shape_bullet.cpp435
-rw-r--r--modules/bullet/shape_bullet.h225
-rw-r--r--modules/bullet/shape_owner_bullet.cpp32
-rw-r--r--modules/bullet/shape_owner_bullet.h52
-rw-r--r--modules/bullet/slider_joint_bullet.cpp385
-rw-r--r--modules/bullet/slider_joint_bullet.h118
-rw-r--r--modules/bullet/soft_body_bullet.cpp303
-rw-r--r--modules/bullet/soft_body_bullet.h136
-rw-r--r--modules/bullet/space_bullet.cpp1101
-rw-r--r--modules/bullet/space_bullet.h194
-rw-r--r--modules/gdnative/SCsub88
-rw-r--r--modules/gdnative/arvr/SCsub (renamed from modules/gdnative/nativearvr/SCsub)0
-rw-r--r--modules/gdnative/arvr/arvr_interface_gdnative.cpp (renamed from modules/gdnative/nativearvr/arvr_interface_gdnative.cpp)198
-rw-r--r--modules/gdnative/arvr/arvr_interface_gdnative.h (renamed from modules/gdnative/nativearvr/arvr_interface_gdnative.h)10
-rw-r--r--modules/gdnative/arvr/config.py (renamed from modules/gdnative/nativearvr/config.py)0
-rw-r--r--modules/gdnative/arvr/register_types.cpp39
-rw-r--r--modules/gdnative/arvr/register_types.h (renamed from modules/gdnative/nativearvr/register_types.h)4
-rw-r--r--modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml9
-rw-r--r--modules/gdnative/doc_classes/GDNative.xml6
-rw-r--r--modules/gdnative/gdnative.cpp67
-rw-r--r--modules/gdnative/gdnative.h12
-rw-r--r--modules/gdnative/gdnative/array.cpp5
-rw-r--r--modules/gdnative/gdnative/basis.cpp2
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp6
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp262
-rw-r--r--modules/gdnative/gdnative/string.cpp28
-rw-r--r--modules/gdnative/gdnative_api.json11090
-rw-r--r--modules/gdnative/include/arvr/godot_arvr.h (renamed from modules/gdnative/include/nativearvr/godot_nativearvr.h)25
-rw-r--r--modules/gdnative/include/gdnative/array.h11
-rw-r--r--modules/gdnative/include/gdnative/basis.h11
-rw-r--r--modules/gdnative/include/gdnative/color.h9
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h11
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h6
-rw-r--r--modules/gdnative/include/gdnative/node_path.h9
-rw-r--r--modules/gdnative/include/gdnative/plane.h9
-rw-r--r--modules/gdnative/include/gdnative/pool_arrays.h133
-rw-r--r--modules/gdnative/include/gdnative/quat.h9
-rw-r--r--modules/gdnative/include/gdnative/rect2.h9
-rw-r--r--modules/gdnative/include/gdnative/rect3.h9
-rw-r--r--modules/gdnative/include/gdnative/rid.h9
-rw-r--r--modules/gdnative/include/gdnative/string.h10
-rw-r--r--modules/gdnative/include/gdnative/string_name.h9
-rw-r--r--modules/gdnative/include/gdnative/transform.h9
-rw-r--r--modules/gdnative/include/gdnative/transform2d.h9
-rw-r--r--modules/gdnative/include/gdnative/variant.h9
-rw-r--r--modules/gdnative/include/gdnative/vector2.h9
-rw-r--r--modules/gdnative/include/gdnative/vector3.h9
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h171
-rw-r--r--modules/gdnative/nativearvr/register_types.cpp414
-rw-r--r--modules/gdnative/nativescript/SCsub1
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp2
-rw-r--r--modules/gdnative/nativescript/api_generator.h2
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp58
-rw-r--r--modules/gdnative/nativescript/nativescript.h9
-rw-r--r--modules/gdnative/nativescript/register_types.cpp50
-rw-r--r--modules/gdnative/pluginscript/SCsub9
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp181
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h90
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp435
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h132
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp113
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h62
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp449
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h127
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp118
-rw-r--r--modules/gdnative/pluginscript/register_types.h31
-rw-r--r--modules/gdnative/register_types.cpp84
-rw-r--r--modules/gdscript/gd_editor.cpp66
-rw-r--r--modules/gdscript/gd_function.cpp130
-rw-r--r--modules/gdscript/gd_functions.cpp22
-rw-r--r--modules/gdscript/gd_functions.h2
-rw-r--r--modules/gdscript/gd_parser.cpp10
-rw-r--r--modules/gdscript/gd_script.cpp7
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--modules/gdscript/gd_tokenizer.cpp3
-rw-r--r--modules/gdscript/gd_tokenizer.h1
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml46
-rw-r--r--modules/gridmap/grid_map.cpp33
-rw-r--r--modules/gridmap/grid_map.h5
-rw-r--r--modules/hdr/image_loader_hdr.cpp4
-rw-r--r--modules/mobile_vr/mobile_interface.cpp23
-rw-r--r--modules/mobile_vr/mobile_interface.h4
-rw-r--r--modules/mono/SCsub145
-rw-r--r--modules/mono/config.py89
-rw-r--r--modules/mono/csharp_script.cpp298
-rw-r--r--modules/mono/csharp_script.h17
-rw-r--r--modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs66
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.sln34
-rw-r--r--modules/mono/editor/bindings_generator.cpp1218
-rw-r--r--modules/mono/editor/bindings_generator.h7
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp103
-rw-r--r--modules/mono/editor/godotsharp_builds.h9
-rw-r--r--modules/mono/editor/godotsharp_editor.cpp76
-rw-r--r--modules/mono/editor/godotsharp_editor.h24
-rw-r--r--modules/mono/editor/mono_bottom_panel.cpp37
-rw-r--r--modules/mono/editor/mono_bottom_panel.h4
-rw-r--r--modules/mono/glue/cs_files/Color.cs1180
-rw-r--r--modules/mono/glue/cs_files/ExportAttribute.cs6
-rw-r--r--modules/mono/glue/cs_files/MarshalUtils.cs2
-rw-r--r--modules/mono/glue/cs_files/Plane.cs418
-rw-r--r--modules/mono/glue/cs_files/Rect3.cs954
-rw-r--r--modules/mono/glue/cs_files/ToolAttribute.cs2
-rw-r--r--modules/mono/godotsharp_dirs.cpp30
-rw-r--r--modules/mono/mono_gc_handle.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp31
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp9
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp32
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp20
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp41
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp8
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h12
-rw-r--r--modules/mono/mono_reg_utils.py94
-rw-r--r--modules/mono/signal_awaiter_utils.cpp77
-rw-r--r--modules/mono/signal_awaiter_utils.h19
-rw-r--r--modules/mono/utils/path_utils.cpp6
-rw-r--r--modules/mono/utils/string_utils.cpp29
-rw-r--r--modules/mono/utils/string_utils.h6
-rw-r--r--modules/openssl/stream_peer_openssl.cpp6
-rw-r--r--modules/openssl/stream_peer_openssl.h2
-rw-r--r--modules/opus/audio_stream_opus.cpp6
-rw-r--r--modules/opus/audio_stream_opus.h2
-rw-r--r--modules/regex/SCsub2
-rw-r--r--modules/visual_script/visual_script.cpp9
-rw-r--r--modules/visual_script/visual_script.h3
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp97
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h5
-rw-r--r--modules/visual_script/visual_script_editor.cpp19
-rw-r--r--modules/visual_script/visual_script_expression.cpp3
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp2
-rw-r--r--modules/visual_script/visual_script_nodes.cpp7
-rw-r--r--modules/visual_script/visual_script_nodes.h2
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp4
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp8
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.h2
177 files changed, 21705 insertions, 8391 deletions
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
new file mode 100644
index 0000000000..7a37cca130
--- /dev/null
+++ b/modules/bullet/SCsub
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+Import('env')
+
+# build only version 2
+# Bullet 2.87
+bullet_src__2_x = [
+ # 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/btMinkowskiSumShape.cpp"
+ , "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp"
+ , "BulletCollision/CollisionShapes/btMultiSphereShape.cpp"
+ , "BulletCollision/CollisionShapes/btOptimizedBvh.cpp"
+ , "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp"
+ , "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.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/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/btMultiBodyConstraintSolver.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp"
+ , "BulletDynamics/Featherstone/btMultiBodyGearConstraint.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"
+
+ # clew
+ , "clew/clew.c"
+
+ # LinearMath
+ , "LinearMath/btAlignedAllocator.cpp"
+ , "LinearMath/btConvexHull.cpp"
+ , "LinearMath/btConvexHullComputer.cpp"
+ , "LinearMath/btGeometryUtil.cpp"
+ , "LinearMath/btPolarDecomposition.cpp"
+ , "LinearMath/btQuickprof.cpp"
+ , "LinearMath/btSerializer.cpp"
+ , "LinearMath/btSerializer64.cpp"
+ , "LinearMath/btThreads.cpp"
+ , "LinearMath/btVector3.cpp"
+ ]
+
+thirdparty_dir = "#thirdparty/bullet/"
+thirdparty_src = thirdparty_dir + "src/"
+
+bullet_sources = [thirdparty_src + file for file in bullet_src__2_x]
+
+# include headers
+env.Append(CPPPATH=[thirdparty_src])
+
+env.add_source_files(env.modules_sources, bullet_sources)
+
+# Godot source files
+env.add_source_files(env.modules_sources, "*.cpp")
+
+Export('env')
diff --git a/modules/bullet/SCsub_with_lib b/modules/bullet/SCsub_with_lib
new file mode 100644
index 0000000000..b362a686ff
--- /dev/null
+++ b/modules/bullet/SCsub_with_lib
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+Import('env')
+
+thirdparty_dir = "#thirdparty/bullet/"
+thirdparty_lib = thirdparty_dir + "Win64/lib/"
+
+bullet_libs = [
+ "Bullet2FileLoader",
+ "Bullet3Collision",
+ "Bullet3Common",
+ "Bullet3Dynamics",
+ "Bullet3Geometry",
+ "Bullet3OpenCL_clew",
+ "BulletCollision",
+ "BulletDynamics",
+ "BulletInverseDynamics",
+ "BulletSoftBody",
+ "LinearMath"
+ ]
+
+thirdparty_src = thirdparty_dir + "src/"
+# include headers
+env.Append(CPPPATH=[thirdparty_src])
+
+# lib
+env.Append(LIBPATH=[thirdparty_dir + "/Win64/lib/"])
+
+bullet_libs = [file+'.lib' for file in bullet_libs]
+# LIBS doesn't work in windows
+env.Append(LINKFLAGS=bullet_libs)
+
+env.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
new file mode 100644
index 0000000000..54024b4f90
--- /dev/null
+++ b/modules/bullet/area_bullet.cpp
@@ -0,0 +1,284 @@
+/*************************************************************************/
+/* area_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "btBulletCollisionCommon.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "collision_object_bullet.h"
+#include "space_bullet.h"
+
+AreaBullet::AreaBullet()
+ : RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA),
+ monitorable(true),
+ isScratched(false),
+ spOv_mode(PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED),
+ spOv_gravityPoint(false),
+ spOv_gravityPointDistanceScale(0),
+ spOv_gravityPointAttenuation(1),
+ spOv_gravityVec(0, -1, 0),
+ spOv_gravityMag(10),
+ spOv_linearDump(0.1),
+ spOv_angularDump(1),
+ spOv_priority(0) {
+
+ btGhost = bulletnew(btGhostObject);
+ btGhost->setCollisionShape(compoundShape);
+ 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() {
+ remove_all_overlapping_instantly();
+}
+
+void AreaBullet::dispatch_callbacks() {
+ if (!isScratched)
+ return;
+ isScratched = false;
+
+ // Reverse order because I've to remove EXIT objects
+ for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
+ OverlappingObjectData &otherObj = overlappingObjects[i];
+
+ switch (otherObj.state) {
+ case OVERLAP_STATE_ENTER:
+ otherObj.state = OVERLAP_STATE_INSIDE;
+ call_event(otherObj.object, PhysicsServer::AREA_BODY_ADDED);
+ otherObj.object->on_enter_area(this);
+ break;
+ case OVERLAP_STATE_EXIT:
+ call_event(otherObj.object, PhysicsServer::AREA_BODY_REMOVED);
+ otherObj.object->on_exit_area(this);
+ overlappingObjects.remove(i); // Remove after callback
+ break;
+ }
+ }
+}
+
+void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer::AreaBodyStatus p_status) {
+
+ InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())];
+ Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id);
+
+ if (!areaGodoObject) {
+ event.event_callback_id = 0;
+ return;
+ }
+
+ call_event_res[0] = p_status;
+ call_event_res[1] = p_otherObject->get_self(); // Other body
+ call_event_res[2] = p_otherObject->get_instance_id(); // instance ID
+ call_event_res[3] = 0; // other_body_shape ID
+ call_event_res[4] = 0; // self_shape ID
+
+ Variant::CallError outResp;
+ areaGodoObject->call(event.event_callback_method, (const Variant **)call_event_res_ptr, 5, outResp);
+}
+
+void AreaBullet::scratch() {
+ if (isScratched)
+ return;
+ isScratched = true;
+}
+
+void AreaBullet::remove_all_overlapping_instantly() {
+ CollisionObjectBullet *supportObject;
+ for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
+ supportObject = overlappingObjects[i].object;
+ call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED);
+ supportObject->on_exit_area(this);
+ }
+ overlappingObjects.clear();
+}
+
+void AreaBullet::remove_overlapping_instantly(CollisionObjectBullet *p_object) {
+ CollisionObjectBullet *supportObject;
+ for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
+ supportObject = overlappingObjects[i].object;
+ if (supportObject == p_object) {
+ call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED);
+ supportObject->on_exit_area(this);
+ overlappingObjects.remove(i);
+ break;
+ }
+ }
+}
+
+int AreaBullet::find_overlapping_object(CollisionObjectBullet *p_colObj) {
+ const int size = overlappingObjects.size();
+ for (int i = 0; i < size; ++i) {
+ if (overlappingObjects[i].object == p_colObj) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void AreaBullet::set_monitorable(bool p_monitorable) {
+ monitorable = p_monitorable;
+}
+
+bool AreaBullet::is_monitoring() const {
+ return get_godot_object_flags() & GOF_IS_MONITORING_AREA;
+}
+
+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) {
+ 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);
+ }
+}
+
+void AreaBullet::add_overlap(CollisionObjectBullet *p_otherObject) {
+ scratch();
+ overlappingObjects.push_back(OverlappingObjectData(p_otherObject, OVERLAP_STATE_ENTER));
+ p_otherObject->notify_new_overlap(this);
+}
+
+void AreaBullet::put_overlap_as_exit(int p_index) {
+ scratch();
+ overlappingObjects[p_index].state = OVERLAP_STATE_EXIT;
+}
+
+void AreaBullet::put_overlap_as_inside(int p_index) {
+ // This check is required to be sure this body was inside
+ if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) {
+ overlappingObjects[p_index].state = OVERLAP_STATE_INSIDE;
+ }
+}
+
+void AreaBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value) {
+ switch (p_param) {
+ case PhysicsServer::AREA_PARAM_GRAVITY:
+ set_spOv_gravityMag(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ set_spOv_gravityVec(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ set_spOv_linearDump(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ set_spOv_angularDump(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_PRIORITY:
+ set_spOv_priority(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ set_spOv_gravityPoint(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ set_spOv_gravityPointDistanceScale(p_value);
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ set_spOv_gravityPointAttenuation(p_value);
+ break;
+ default:
+ print_line("The Bullet areas dosn't suppot this param: " + itos(p_param));
+ }
+}
+
+Variant AreaBullet::get_param(PhysicsServer::AreaParameter p_param) const {
+ switch (p_param) {
+ case PhysicsServer::AREA_PARAM_GRAVITY:
+ return spOv_gravityMag;
+ case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ return spOv_gravityVec;
+ case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ return spOv_linearDump;
+ case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ return spOv_angularDump;
+ case PhysicsServer::AREA_PARAM_PRIORITY:
+ return spOv_priority;
+ case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ return spOv_gravityPoint;
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ return spOv_gravityPointDistanceScale;
+ case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ return spOv_gravityPointAttenuation;
+ default:
+ print_line("The Bullet areas dosn't suppot this param: " + itos(p_param));
+ return Variant();
+ }
+}
+
+void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method) {
+ InOutEventCallback &ev = eventsCallbacks[static_cast<int>(p_callbackObjectType)];
+ ev.event_callback_id = p_id;
+ ev.event_callback_method = p_method;
+
+ /// Set if monitoring
+ if (eventsCallbacks[0].event_callback_id || eventsCallbacks[1].event_callback_id) {
+ 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));
+ }
+}
+
+bool AreaBullet::has_event_callback(Type p_callbackObjectType) {
+ return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id;
+}
+
+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
new file mode 100644
index 0000000000..f6e3b7e902
--- /dev/null
+++ b/modules/bullet/area_bullet.h
@@ -0,0 +1,169 @@
+/*************************************************************************/
+/* area_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 AREABULLET_H
+#define AREABULLET_H
+
+#include "collision_object_bullet.h"
+#include "core/vector.h"
+#include "servers/physics_server.h"
+#include "space_bullet.h"
+
+class btGhostObject;
+
+class AreaBullet : public RigidCollisionObjectBullet {
+ friend void SpaceBullet::check_ghost_overlaps();
+
+public:
+ struct InOutEventCallback {
+ ObjectID event_callback_id;
+ StringName event_callback_method;
+
+ InOutEventCallback()
+ : event_callback_id(0) {}
+ };
+
+ 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 OverlappingObjectData {
+ CollisionObjectBullet *object;
+ OverlapState state;
+
+ OverlappingObjectData()
+ : object(NULL), state(OVERLAP_STATE_ENTER) {}
+ OverlappingObjectData(CollisionObjectBullet *p_object, OverlapState p_state)
+ : object(p_object), state(p_state) {}
+ OverlappingObjectData(const OverlappingObjectData &other) {
+ operator=(other);
+ }
+ void operator=(const OverlappingObjectData &other) {
+ object = other.object;
+ state = other.state;
+ }
+ };
+
+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;
+ Vector<OverlappingObjectData> overlappingObjects;
+ bool monitorable;
+
+ PhysicsServer::AreaSpaceOverrideMode spOv_mode;
+ bool spOv_gravityPoint;
+ real_t spOv_gravityPointDistanceScale;
+ real_t spOv_gravityPointAttenuation;
+ Vector3 spOv_gravityVec;
+ real_t spOv_gravityMag;
+ real_t spOv_linearDump;
+ real_t spOv_angularDump;
+ int spOv_priority;
+
+ bool isScratched;
+
+ InOutEventCallback eventsCallbacks[2];
+
+public:
+ AreaBullet();
+ ~AreaBullet();
+
+ _FORCE_INLINE_ btGhostObject *get_bt_ghost() const { return btGhost; }
+ int find_overlapping_object(CollisionObjectBullet *p_colObj);
+
+ void set_monitorable(bool p_monitorable);
+ _FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
+
+ bool is_monitoring() const;
+
+ _FORCE_INLINE_ void set_spOv_mode(PhysicsServer::AreaSpaceOverrideMode p_mode) { spOv_mode = p_mode; }
+ _FORCE_INLINE_ PhysicsServer::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 reload_body();
+ virtual void set_space(SpaceBullet *p_space);
+
+ virtual void dispatch_callbacks();
+ void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer::AreaBodyStatus p_status);
+ void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
+ void scratch();
+
+ void remove_all_overlapping_instantly();
+ // Dispatch the callbacks and removes from overlapping list
+ void remove_overlapping_instantly(CollisionObjectBullet *p_object);
+
+ virtual void on_collision_filters_change();
+ virtual void on_collision_checker_start() {}
+
+ void add_overlap(CollisionObjectBullet *p_otherObject);
+ void put_overlap_as_exit(int p_index);
+ void put_overlap_as_inside(int p_index);
+
+ void set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value);
+ Variant get_param(PhysicsServer::AreaParameter p_param) const;
+
+ void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method);
+ bool has_event_callback(Type p_callbackObjectType);
+
+ virtual void on_enter_area(AreaBullet *p_area);
+ virtual void on_exit_area(AreaBullet *p_area);
+};
+
+#endif
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
new file mode 100644
index 0000000000..ac95faaac6
--- /dev/null
+++ b/modules/bullet/btRayShape.cpp
@@ -0,0 +1,94 @@
+/*************************************************************************/
+/* btRayShape.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btAabbUtil2.h"
+#include "math/math_funcs.h"
+
+btRayShape::btRayShape(btScalar length)
+ : btConvexInternalShape(),
+ m_shapeAxis(0, 0, 1) {
+ m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
+ setLength(length);
+}
+
+btRayShape::~btRayShape() {
+}
+
+void btRayShape::setLength(btScalar p_length) {
+
+ m_length = p_length;
+ reload_cache();
+}
+
+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 {
+#define MARGIN_BROADPHASE 0.1
+ btVector3 localAabbMin(0, 0, 0);
+ btVector3 localAabbMax(m_shapeAxis * m_length);
+ btTransformAabb(localAabbMin, localAabbMax, MARGIN_BROADPHASE, 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_collisionMargin;
+
+ m_cacheSupportPoint.setIdentity();
+ m_cacheSupportPoint.setOrigin(m_shapeAxis * m_cacheScaledLength);
+}
diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h
new file mode 100644
index 0000000000..1b63fb477c
--- /dev/null
+++ b/modules/bullet/btRayShape.h
@@ -0,0 +1,87 @@
+/*************************************************************************/
+/* btRayShape.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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;
+ /// The default axis is the z
+ btVector3 m_shapeAxis;
+
+ 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; }
+
+ 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
new file mode 100644
index 0000000000..7f95d16ba6
--- /dev/null
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -0,0 +1,1364 @@
+/*************************************************************************/
+/* bullet_physics_server.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btVector3.h"
+#include "bullet_utilities.h"
+#include "class_db.h"
+#include "cone_twist_joint_bullet.h"
+#include "core/error_macros.h"
+#include "core/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 <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_PRINTS("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, disableCollisionsBetweenLinkedBodies) \
+ body->get_space()->add_constraint(joint, disableCollisionsBetweenLinkedBodies);
+// <--------------- Joint creation asserts
+
+btEmptyShape *BulletPhysicsServer::emptyShape(ShapeBullet::create_shape_empty());
+
+btEmptyShape *BulletPhysicsServer::get_empty_shape() {
+ return emptyShape;
+}
+
+void BulletPhysicsServer::_bind_methods() {
+ //ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer::DoTest);
+}
+
+BulletPhysicsServer::BulletPhysicsServer()
+ : PhysicsServer(),
+ active(true),
+ active_spaces_count(0) {}
+
+BulletPhysicsServer::~BulletPhysicsServer() {}
+
+RID BulletPhysicsServer::shape_create(ShapeType p_shape) {
+ ShapeBullet *shape = NULL;
+
+ switch (p_shape) {
+ case SHAPE_PLANE: {
+
+ shape = bulletnew(PlaneShapeBullet);
+ } break;
+ case SHAPE_SPHERE: {
+
+ shape = bulletnew(SphereShapeBullet);
+ } break;
+ case SHAPE_BOX: {
+
+ shape = bulletnew(BoxShapeBullet);
+ } break;
+ case SHAPE_CAPSULE: {
+
+ shape = bulletnew(CapsuleShapeBullet);
+ } 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:
+ defaul:
+ ERR_FAIL_V(RID());
+ break;
+ }
+
+ CreateThenReturnRID(shape_owner, shape)
+}
+
+void BulletPhysicsServer::shape_set_data(RID p_shape, const Variant &p_data) {
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND(!shape);
+ shape->set_data(p_data);
+}
+
+void BulletPhysicsServer::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {
+ //WARN_PRINT("Bias not supported by Bullet physics engine");
+}
+
+PhysicsServer::ShapeType BulletPhysicsServer::shape_get_type(RID p_shape) const {
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND_V(!shape, PhysicsServer::SHAPE_CUSTOM);
+ return shape->get_type();
+}
+
+Variant BulletPhysicsServer::shape_get_data(RID p_shape) const {
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND_V(!shape, Variant());
+ return shape->get_data();
+}
+
+real_t BulletPhysicsServer::shape_get_custom_solver_bias(RID p_shape) const {
+ //WARN_PRINT("Bias not supported by Bullet physics engine");
+ return 0.;
+}
+
+RID BulletPhysicsServer::space_create() {
+ SpaceBullet *space = bulletnew(SpaceBullet(false));
+ CreateThenReturnRID(space_owner, space);
+}
+
+void BulletPhysicsServer::space_set_active(RID p_space, bool p_active) {
+
+ SpaceBullet *space = space_owner.get(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 BulletPhysicsServer::space_is_active(RID p_space) const {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND_V(!space, false);
+
+ return -1 != active_spaces.find(space);
+}
+
+void BulletPhysicsServer::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND(!space);
+ space->set_param(p_param, p_value);
+}
+
+real_t BulletPhysicsServer::space_get_param(RID p_space, SpaceParameter p_param) const {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND_V(!space, 0);
+ return space->get_param(p_param);
+}
+
+PhysicsDirectSpaceState *BulletPhysicsServer::space_get_direct_state(RID p_space) {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND_V(!space, NULL);
+
+ return space->get_direct_state();
+}
+
+void BulletPhysicsServer::space_set_debug_contacts(RID p_space, int p_max_contacts) {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND(!space);
+
+ space->set_debug_contacts(p_max_contacts);
+}
+
+Vector<Vector3> BulletPhysicsServer::space_get_contacts(RID p_space) const {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND_V(!space, Vector<Vector3>());
+
+ return space->get_debug_contacts();
+}
+
+int BulletPhysicsServer::space_get_contact_count(RID p_space) const {
+ SpaceBullet *space = space_owner.get(p_space);
+ ERR_FAIL_COND_V(!space, 0);
+
+ return space->get_debug_contact_count();
+}
+
+RID BulletPhysicsServer::area_create() {
+ AreaBullet *area = bulletnew(AreaBullet);
+ area->set_collision_layer(1);
+ area->set_collision_mask(1);
+ CreateThenReturnRID(area_owner, area)
+}
+
+void BulletPhysicsServer::area_set_space(RID p_area, RID p_space) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ SpaceBullet *space = NULL;
+ if (p_space.is_valid()) {
+ space = space_owner.get(p_space);
+ ERR_FAIL_COND(!space);
+ }
+ area->set_space(space);
+}
+
+RID BulletPhysicsServer::area_get_space(RID p_area) const {
+ AreaBullet *area = area_owner.get(p_area);
+ return area->get_space()->get_self();
+}
+
+void BulletPhysicsServer::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area)
+
+ area->set_spOv_mode(p_mode);
+}
+
+PhysicsServer::AreaSpaceOverrideMode BulletPhysicsServer::area_get_space_override_mode(RID p_area) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED);
+
+ return area->get_spOv_mode();
+}
+
+void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND(!shape);
+
+ area->add_shape(shape, p_transform);
+}
+
+void BulletPhysicsServer::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND(!shape);
+
+ area->set_shape(p_shape_idx, shape);
+}
+
+void BulletPhysicsServer::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_shape_transform(p_shape_idx, p_transform);
+}
+
+int BulletPhysicsServer::area_get_shape_count(RID p_area) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, 0);
+
+ return area->get_shape_count();
+}
+
+RID BulletPhysicsServer::area_get_shape(RID p_area, int p_shape_idx) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, RID());
+
+ return area->get_shape(p_shape_idx)->get_self();
+}
+
+Transform BulletPhysicsServer::area_get_shape_transform(RID p_area, int p_shape_idx) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, Transform());
+
+ return area->get_shape_transform(p_shape_idx);
+}
+
+void BulletPhysicsServer::area_remove_shape(RID p_area, int p_shape_idx) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ return area->remove_shape(p_shape_idx);
+}
+
+void BulletPhysicsServer::area_clear_shapes(RID p_area) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ for (int i = area->get_shape_count(); 0 < i; --i)
+ area->remove_shape(0);
+}
+
+void BulletPhysicsServer::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_shape_disabled(p_shape_idx, p_disabled);
+}
+
+void BulletPhysicsServer::area_attach_object_instance_id(RID p_area, ObjectID p_ID) {
+ if (space_owner.owns(p_area)) {
+ return;
+ }
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_instance_id(p_ID);
+}
+
+ObjectID BulletPhysicsServer::area_get_object_instance_id(RID p_area) const {
+ if (space_owner.owns(p_area)) {
+ return 0;
+ }
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, ObjectID());
+ return area->get_instance_id();
+}
+
+void BulletPhysicsServer::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
+ if (space_owner.owns(p_area)) {
+ SpaceBullet *space = space_owner.get(p_area);
+ if (space) {
+ space->set_param(p_param, p_value);
+ }
+ } else {
+
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_param(p_param, p_value);
+ }
+}
+
+Variant BulletPhysicsServer::area_get_param(RID p_area, AreaParameter p_param) const {
+ if (space_owner.owns(p_area)) {
+ SpaceBullet *space = space_owner.get(p_area);
+ return space->get_param(p_param);
+ } else {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, Variant());
+
+ return area->get_param(p_param);
+ }
+}
+
+void BulletPhysicsServer::area_set_transform(RID p_area, const Transform &p_transform) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_transform(p_transform);
+}
+
+Transform BulletPhysicsServer::area_get_transform(RID p_area) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, Transform());
+ return area->get_transform();
+}
+
+void BulletPhysicsServer::area_set_collision_mask(RID p_area, uint32_t p_mask) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_collision_mask(p_mask);
+}
+
+void BulletPhysicsServer::area_set_collision_layer(RID p_area, uint32_t p_layer) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_collision_layer(p_layer);
+}
+
+void BulletPhysicsServer::area_set_monitorable(RID p_area, bool p_monitorable) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_monitorable(p_monitorable);
+}
+
+void BulletPhysicsServer::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+}
+
+void BulletPhysicsServer::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+}
+
+void BulletPhysicsServer::area_set_ray_pickable(RID p_area, bool p_enable) {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_ray_pickable(p_enable);
+}
+
+bool BulletPhysicsServer::area_is_ray_pickable(RID p_area) const {
+ AreaBullet *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, false);
+ return area->is_ray_pickable();
+}
+
+RID BulletPhysicsServer::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 BulletPhysicsServer::body_set_space(RID p_body, RID p_space) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ SpaceBullet *space = NULL;
+
+ if (p_space.is_valid()) {
+ space = space_owner.get(p_space);
+ ERR_FAIL_COND(!space);
+ }
+
+ if (body->get_space() == space)
+ return; //pointles
+
+ body->set_space(space);
+}
+
+RID BulletPhysicsServer::body_get_space(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, RID());
+
+ SpaceBullet *space = body->get_space();
+ if (!space)
+ return RID();
+ return space->get_self();
+}
+
+void BulletPhysicsServer::body_set_mode(RID p_body, PhysicsServer::BodyMode p_mode) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_mode(p_mode);
+}
+
+PhysicsServer::BodyMode BulletPhysicsServer::body_get_mode(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, BODY_MODE_STATIC);
+ return body->get_mode();
+}
+
+void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform) {
+
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND(!shape);
+
+ body->add_shape(shape, p_transform);
+}
+
+void BulletPhysicsServer::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ ShapeBullet *shape = shape_owner.get(p_shape);
+ ERR_FAIL_COND(!shape);
+
+ body->set_shape(p_shape_idx, shape);
+}
+
+void BulletPhysicsServer::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_shape_transform(p_shape_idx, p_transform);
+}
+
+int BulletPhysicsServer::body_get_shape_count(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+ return body->get_shape_count();
+}
+
+RID BulletPhysicsServer::body_get_shape(RID p_body, int p_shape_idx) const {
+ RigidBodyBullet *body = rigid_body_owner.get(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();
+}
+
+Transform BulletPhysicsServer::body_get_shape_transform(RID p_body, int p_shape_idx) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, Transform());
+ return body->get_shape_transform(p_shape_idx);
+}
+
+void BulletPhysicsServer::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_shape_disabled(p_shape_idx, p_disabled);
+}
+
+void BulletPhysicsServer::body_remove_shape(RID p_body, int p_shape_idx) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->remove_shape(p_shape_idx);
+}
+
+void BulletPhysicsServer::body_clear_shapes(RID p_body) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->remove_all_shapes();
+}
+
+void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, uint32_t p_ID) {
+ CollisionObjectBullet *body = get_collisin_object(p_body);
+ if (!body) {
+ body = soft_body_owner.get(p_body);
+ }
+ ERR_FAIL_COND(!body);
+
+ body->set_instance_id(p_ID);
+}
+
+uint32_t BulletPhysicsServer::body_get_object_instance_id(RID p_body) const {
+ CollisionObjectBullet *body = get_collisin_object(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_instance_id();
+}
+
+void BulletPhysicsServer::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_continuous_collision_detection(p_enable);
+}
+
+bool BulletPhysicsServer::body_is_continuous_collision_detection_enabled(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+
+ return body->is_continuous_collision_detection_enabled();
+}
+
+void BulletPhysicsServer::body_set_collision_layer(RID p_body, uint32_t p_layer) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_collision_layer(p_layer);
+}
+
+uint32_t BulletPhysicsServer::body_get_collision_layer(RID p_body) const {
+ const RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_collision_layer();
+}
+
+void BulletPhysicsServer::body_set_collision_mask(RID p_body, uint32_t p_mask) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_collision_mask(p_mask);
+}
+
+uint32_t BulletPhysicsServer::body_get_collision_mask(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_collision_mask();
+}
+
+void BulletPhysicsServer::body_set_user_flags(RID p_body, uint32_t p_flags) {
+ WARN_PRINT("This function si not currently supported by bullet and Godot");
+}
+
+uint32_t BulletPhysicsServer::body_get_user_flags(RID p_body) const {
+ WARN_PRINT("This function si not currently supported by bullet and Godot");
+ return 0;
+}
+
+void BulletPhysicsServer::body_set_param(RID p_body, BodyParameter p_param, float p_value) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_param(p_param, p_value);
+}
+
+float BulletPhysicsServer::body_get_param(RID p_body, BodyParameter p_param) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_param(p_param);
+}
+
+void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ if (body->get_kinematic_utilities()) {
+
+ body->get_kinematic_utilities()->setSafeMargin(p_margin);
+ }
+}
+
+real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ if (body->get_kinematic_utilities()) {
+
+ return body->get_kinematic_utilities()->safe_margin;
+ }
+
+ return 0;
+}
+
+void BulletPhysicsServer::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_state(p_state, p_variant);
+}
+
+Variant BulletPhysicsServer::body_get_state(RID p_body, BodyState p_state) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, Variant());
+
+ return body->get_state(p_state);
+}
+
+void BulletPhysicsServer::body_set_applied_force(RID p_body, const Vector3 &p_force) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_applied_force(p_force);
+}
+
+Vector3 BulletPhysicsServer::body_get_applied_force(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, Vector3());
+ return body->get_applied_force();
+}
+
+void BulletPhysicsServer::body_set_applied_torque(RID p_body, const Vector3 &p_torque) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_applied_torque(p_torque);
+}
+
+Vector3 BulletPhysicsServer::body_get_applied_torque(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, Vector3());
+
+ return body->get_applied_torque();
+}
+
+void BulletPhysicsServer::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_impulse(p_pos, p_impulse);
+}
+
+void BulletPhysicsServer::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->apply_torque_impulse(p_impulse);
+}
+
+void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {
+ RigidBodyBullet *body = rigid_body_owner.get(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 BulletPhysicsServer::body_set_axis_lock(RID p_body, PhysicsServer::BodyAxisLock p_lock) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_axis_lock(p_lock);
+}
+
+PhysicsServer::BodyAxisLock BulletPhysicsServer::body_get_axis_lock(RID p_body) const {
+ const RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, BODY_AXIS_LOCK_DISABLED);
+ return body->get_axis_lock();
+}
+
+void BulletPhysicsServer::body_add_collision_exception(RID p_body, RID p_body_b) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b);
+ ERR_FAIL_COND(!other_body);
+
+ body->add_collision_exception(other_body);
+}
+
+void BulletPhysicsServer::body_remove_collision_exception(RID p_body, RID p_body_b) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b);
+ ERR_FAIL_COND(!other_body);
+
+ body->remove_collision_exception(other_body);
+}
+
+void BulletPhysicsServer::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
+ RigidBodyBullet *body = rigid_body_owner.get(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 BulletPhysicsServer::body_set_max_contacts_reported(RID p_body, int p_contacts) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_max_collisions_detection(p_contacts);
+}
+
+int BulletPhysicsServer::body_get_max_contacts_reported(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_max_collisions_detection();
+}
+
+void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold) {
+ WARN_PRINT("Not supported by bullet and even Godot");
+}
+
+float BulletPhysicsServer::body_get_contacts_reported_depth_threshold(RID p_body) const {
+ WARN_PRINT("Not supported by bullet and even Godot");
+ return 0.;
+}
+
+void BulletPhysicsServer::body_set_omit_force_integration(RID p_body, bool p_omit) {
+ WARN_PRINT("Not supported by bullet");
+}
+
+bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const {
+ WARN_PRINT("Not supported by bullet");
+ return false;
+}
+
+void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_force_integration_callback(p_receiver->get_instance_id(), p_method, p_udata);
+}
+
+void BulletPhysicsServer::body_set_ray_pickable(RID p_body, bool p_enable) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_ray_pickable(p_enable);
+}
+
+bool BulletPhysicsServer::body_is_ray_pickable(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+ return body->is_ray_pickable();
+}
+
+PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) {
+ RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, NULL);
+ return BulletPhysicsDirectBodyState::get_singleton(body);
+}
+
+bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) {
+ RigidBodyBullet *body = rigid_body_owner.get(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, r_result);
+}
+
+RID BulletPhysicsServer::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 BulletPhysicsServer::soft_body_set_space(RID p_body, RID p_space) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ SpaceBullet *space = NULL;
+
+ if (p_space.is_valid()) {
+ space = space_owner.get(p_space);
+ ERR_FAIL_COND(!space);
+ }
+
+ if (body->get_space() == space)
+ return; //pointles
+
+ body->set_space(space);
+}
+
+RID BulletPhysicsServer::soft_body_get_space(RID p_body) const {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, RID());
+
+ SpaceBullet *space = body->get_space();
+ if (!space)
+ return RID();
+ return space->get_self();
+}
+
+void BulletPhysicsServer::soft_body_set_trimesh_body_shape(RID p_body, PoolVector<int> p_indices, PoolVector<Vector3> p_vertices, int p_triangles_num) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_trimesh_body_shape(p_indices, p_vertices, p_triangles_num);
+}
+
+void BulletPhysicsServer::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_collision_layer(p_layer);
+}
+
+uint32_t BulletPhysicsServer::soft_body_get_collision_layer(RID p_body) const {
+ const SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_collision_layer();
+}
+
+void BulletPhysicsServer::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_collision_mask(p_mask);
+}
+
+uint32_t BulletPhysicsServer::soft_body_get_collision_mask(RID p_body) const {
+ const SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_collision_mask();
+}
+
+void BulletPhysicsServer::soft_body_add_collision_exception(RID p_body, RID p_body_b) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b);
+ if (!other_body) {
+ other_body = soft_body_owner.get(p_body_b);
+ }
+ ERR_FAIL_COND(!other_body);
+
+ body->add_collision_exception(other_body);
+}
+
+void BulletPhysicsServer::soft_body_remove_collision_exception(RID p_body, RID p_body_b) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b);
+ if (!other_body) {
+ other_body = soft_body_owner.get(p_body_b);
+ }
+ ERR_FAIL_COND(!other_body);
+
+ body->remove_collision_exception(other_body);
+}
+
+void BulletPhysicsServer::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
+ SoftBodyBullet *body = soft_body_owner.get(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 BulletPhysicsServer::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
+ print_line("TODO MUST BE IMPLEMENTED");
+}
+
+Variant BulletPhysicsServer::soft_body_get_state(RID p_body, BodyState p_state) const {
+ print_line("TODO MUST BE IMPLEMENTED");
+ return Variant();
+}
+
+void BulletPhysicsServer::soft_body_set_transform(RID p_body, const Transform &p_transform) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_transform(p_transform);
+}
+
+Transform BulletPhysicsServer::soft_body_get_transform(RID p_body) const {
+ const SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, Transform());
+
+ return body->get_transform();
+}
+
+void BulletPhysicsServer::soft_body_set_ray_pickable(RID p_body, bool p_enable) {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_ray_pickable(p_enable);
+}
+
+bool BulletPhysicsServer::soft_body_is_ray_pickable(RID p_body) const {
+ SoftBodyBullet *body = soft_body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+ return body->is_ray_pickable();
+}
+
+PhysicsServer::JointType BulletPhysicsServer::joint_get_type(RID p_joint) const {
+ JointBullet *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint, JOINT_PIN);
+ return joint->get_type();
+}
+
+void BulletPhysicsServer::joint_set_solver_priority(RID p_joint, int p_priority) {
+ //WARN_PRINTS("Joint priority not supported by bullet");
+}
+
+int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const {
+ //WARN_PRINTS("Joint priority not supported by bullet");
+ return 0;
+}
+
+RID BulletPhysicsServer::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(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+void BulletPhysicsServer::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.get(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);
+}
+
+float BulletPhysicsServer::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::pin_joint_get_local_a(RID p_joint) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::pin_joint_get_local_b(RID p_joint) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+RID BulletPhysicsServer::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(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+void BulletPhysicsServer::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.get(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);
+}
+
+float BulletPhysicsServer::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+void BulletPhysicsServer::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.get(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);
+}
+
+float BulletPhysicsServer::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+void BulletPhysicsServer::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.get(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);
+}
+
+float BulletPhysicsServer::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A, RID());
+ JointAssertSpace(body_A, "A", RID());
+
+ RigidBodyBullet *body_B = NULL;
+ if (p_body_B.is_valid()) {
+ body_B = rigid_body_owner.get(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, true));
+ AddJointToSpace(body_A, joint, true);
+
+ CreateThenReturnRID(joint_owner, joint);
+}
+
+void BulletPhysicsServer::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.get(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);
+}
+
+float BulletPhysicsServer::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
+ JointBullet *joint = joint_owner.get(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 BulletPhysicsServer::free(RID p_rid) {
+ if (shape_owner.owns(p_rid)) {
+
+ ShapeBullet *shape = shape_owner.get(p_rid);
+
+ // Notify the shape is configured
+ for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) {
+ static_cast<ShapeOwnerBullet *>(element->key())->remove_shape(shape);
+ }
+
+ shape_owner.free(p_rid);
+ bulletdelete(shape);
+ } else if (rigid_body_owner.owns(p_rid)) {
+
+ RigidBodyBullet *body = rigid_body_owner.get(p_rid);
+
+ body->set_space(NULL);
+
+ body->remove_all_shapes(true);
+
+ rigid_body_owner.free(p_rid);
+ bulletdelete(body);
+
+ } else if (soft_body_owner.owns(p_rid)) {
+
+ SoftBodyBullet *body = soft_body_owner.get(p_rid);
+
+ body->set_space(NULL);
+
+ soft_body_owner.free(p_rid);
+ bulletdelete(body);
+
+ } else if (area_owner.owns(p_rid)) {
+
+ AreaBullet *area = area_owner.get(p_rid);
+
+ area->set_space(NULL);
+
+ area->remove_all_shapes(true);
+
+ area_owner.free(p_rid);
+ bulletdelete(area);
+
+ } else if (joint_owner.owns(p_rid)) {
+
+ JointBullet *joint = joint_owner.get(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(p_rid);
+
+ space->remove_all_collision_objects();
+
+ space_set_active(p_rid, false);
+ space_owner.free(p_rid);
+ bulletdelete(space);
+ } else {
+
+ ERR_EXPLAIN("Invalid ID");
+ ERR_FAIL();
+ }
+}
+
+void BulletPhysicsServer::init() {
+ BulletPhysicsDirectBodyState::initSingleton();
+}
+
+void BulletPhysicsServer::step(float p_deltaTime) {
+ if (!active)
+ return;
+
+ BulletPhysicsDirectBodyState::singleton_setDeltaTime(p_deltaTime);
+
+ for (int i = 0; i < active_spaces_count; ++i) {
+
+ active_spaces[i]->step(p_deltaTime);
+ }
+}
+
+void BulletPhysicsServer::sync() {
+}
+
+void BulletPhysicsServer::flush_queries() {
+}
+
+void BulletPhysicsServer::finish() {
+ BulletPhysicsDirectBodyState::destroySingleton();
+}
+
+int BulletPhysicsServer::get_process_info(ProcessInfo p_info) {
+ return 0;
+}
+
+CollisionObjectBullet *BulletPhysicsServer::get_collisin_object(RID p_object) const {
+ if (rigid_body_owner.owns(p_object)) {
+ return rigid_body_owner.getornull(p_object);
+ }
+ if (area_owner.owns(p_object)) {
+ return area_owner.getornull(p_object);
+ }
+ if (soft_body_owner.owns(p_object)) {
+ return soft_body_owner.getornull(p_object);
+ }
+ return NULL;
+}
+
+RigidCollisionObjectBullet *BulletPhysicsServer::get_rigid_collisin_object(RID p_object) const {
+ if (rigid_body_owner.owns(p_object)) {
+ return rigid_body_owner.getornull(p_object);
+ }
+ if (area_owner.owns(p_object)) {
+ return area_owner.getornull(p_object);
+ }
+ return NULL;
+}
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
new file mode 100644
index 0000000000..ad8137ee2f
--- /dev/null
+++ b/modules/bullet/bullet_physics_server.h
@@ -0,0 +1,362 @@
+/*************************************************************************/
+/* bullet_physics_server.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "joint_bullet.h"
+#include "rid.h"
+#include "rigid_body_bullet.h"
+#include "servers/physics_server.h"
+#include "shape_bullet.h"
+#include "soft_body_bullet.h"
+#include "space_bullet.h"
+
+class BulletPhysicsServer : public PhysicsServer {
+ GDCLASS(BulletPhysicsServer, PhysicsServer)
+
+ friend class BulletPhysicsDirectSpaceState;
+
+ bool active;
+ char active_spaces_count;
+ Vector<SpaceBullet *> active_spaces;
+
+ mutable RID_Owner<SpaceBullet> space_owner;
+ mutable RID_Owner<ShapeBullet> shape_owner;
+ mutable RID_Owner<AreaBullet> area_owner;
+ mutable RID_Owner<RigidBodyBullet> rigid_body_owner;
+ mutable RID_Owner<SoftBodyBullet> soft_body_owner;
+ mutable RID_Owner<JointBullet> joint_owner;
+
+private:
+ /// This is used when a collision shape is not active, so the bullet compound shapes index are always sync with godot index
+ static btEmptyShape *emptyShape;
+
+public:
+ static btEmptyShape *get_empty_shape();
+
+protected:
+ static void _bind_methods();
+
+public:
+ BulletPhysicsServer();
+ ~BulletPhysicsServer();
+
+ _FORCE_INLINE_ RID_Owner<SpaceBullet> *get_space_owner() {
+ return &space_owner;
+ }
+ _FORCE_INLINE_ RID_Owner<ShapeBullet> *get_shape_owner() {
+ return &shape_owner;
+ }
+ _FORCE_INLINE_ RID_Owner<AreaBullet> *get_area_owner() {
+ return &area_owner;
+ }
+ _FORCE_INLINE_ RID_Owner<RigidBodyBullet> *get_rigid_body_owner() {
+ return &rigid_body_owner;
+ }
+ _FORCE_INLINE_ RID_Owner<SoftBodyBullet> *get_soft_body_owner() {
+ return &soft_body_owner;
+ }
+ _FORCE_INLINE_ RID_Owner<JointBullet> *get_joint_owner() {
+ return &joint_owner;
+ }
+
+ /* SHAPE API */
+ virtual RID shape_create(ShapeType p_shape);
+ virtual void shape_set_data(RID p_shape, const Variant &p_data);
+ virtual ShapeType shape_get_type(RID p_shape) const;
+ virtual Variant shape_get_data(RID p_shape) const;
+
+ /// Not supported
+ virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias);
+ /// Not supported
+ virtual real_t shape_get_custom_solver_bias(RID p_shape) const;
+
+ /* SPACE API */
+
+ virtual RID space_create();
+ virtual void space_set_active(RID p_space, bool p_active);
+ virtual bool space_is_active(RID p_space) const;
+
+ /// Not supported
+ virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value);
+ /// Not supported
+ virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const;
+
+ virtual PhysicsDirectSpaceState *space_get_direct_state(RID p_space);
+
+ virtual void space_set_debug_contacts(RID p_space, int p_max_contacts);
+ virtual Vector<Vector3> space_get_contacts(RID p_space) const;
+ virtual int space_get_contact_count(RID p_space) const;
+
+ /* 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();
+
+ virtual void area_set_space(RID p_area, RID p_space);
+
+ virtual RID area_get_space(RID p_area) const;
+
+ virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode);
+ virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const;
+
+ virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform());
+ virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape);
+ virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform);
+ virtual int area_get_shape_count(RID p_area) const;
+ virtual RID area_get_shape(RID p_area, int p_shape_idx) const;
+ virtual Transform area_get_shape_transform(RID p_area, int p_shape_idx) const;
+ virtual void area_remove_shape(RID p_area, int p_shape_idx);
+ virtual void area_clear_shapes(RID p_area);
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled);
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID);
+ virtual ObjectID area_get_object_instance_id(RID p_area) const;
+
+ /// 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);
+ virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const;
+
+ virtual void area_set_transform(RID p_area, const Transform &p_transform);
+ virtual Transform area_get_transform(RID p_area) const;
+
+ virtual void area_set_collision_mask(RID p_area, uint32_t p_mask);
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer);
+
+ virtual void area_set_monitorable(RID p_area, bool p_monitorable);
+ virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
+ virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
+ virtual void area_set_ray_pickable(RID p_area, bool p_enable);
+ virtual bool area_is_ray_pickable(RID p_area) const;
+
+ /* RIGID BODY API */
+
+ virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false);
+
+ virtual void body_set_space(RID p_body, RID p_space);
+ virtual RID body_get_space(RID p_body) const;
+
+ virtual void body_set_mode(RID p_body, BodyMode p_mode);
+ virtual BodyMode body_get_mode(RID p_body) const;
+
+ virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform());
+ // Not supported, Please remove and add new shape
+ virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape);
+ virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform);
+
+ virtual int body_get_shape_count(RID p_body) const;
+ virtual RID body_get_shape(RID p_body, int p_shape_idx) const;
+ virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const;
+
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled);
+
+ virtual void body_remove_shape(RID p_body, int p_shape_idx);
+ virtual void body_clear_shapes(RID p_body);
+
+ // Used for Rigid and Soft Bodies
+ virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID);
+ virtual uint32_t body_get_object_instance_id(RID p_body) const;
+
+ virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
+ virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
+
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t body_get_collision_layer(RID p_body) const;
+
+ virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
+ virtual uint32_t body_get_collision_mask(RID p_body) const;
+
+ /// This is not supported by physics server
+ virtual void body_set_user_flags(RID p_body, uint32_t p_flags);
+ /// This is not supported by physics server
+ virtual uint32_t body_get_user_flags(RID p_body) const;
+
+ virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value);
+ virtual float body_get_param(RID p_body, BodyParameter p_param) const;
+
+ virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin);
+ virtual real_t body_get_kinematic_safe_margin(RID p_body) const;
+
+ virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant);
+ virtual Variant body_get_state(RID p_body, BodyState p_state) const;
+
+ virtual void body_set_applied_force(RID p_body, const Vector3 &p_force);
+ virtual Vector3 body_get_applied_force(RID p_body) const;
+
+ virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque);
+ virtual Vector3 body_get_applied_torque(RID p_body) const;
+
+ virtual void body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse);
+ virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse);
+ virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity);
+
+ virtual void body_set_axis_lock(RID p_body, BodyAxisLock p_lock);
+ virtual BodyAxisLock body_get_axis_lock(RID p_body) const;
+
+ virtual void body_add_collision_exception(RID p_body, RID p_body_b);
+ virtual void body_remove_collision_exception(RID p_body, RID p_body_b);
+ virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions);
+
+ virtual void body_set_max_contacts_reported(RID p_body, int p_contacts);
+ virtual int body_get_max_contacts_reported(RID p_body) const;
+
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold);
+ virtual float body_get_contacts_reported_depth_threshold(RID p_body) const;
+
+ virtual void body_set_omit_force_integration(RID p_body, bool p_omit);
+ virtual bool body_is_omitting_force_integration(RID p_body) const;
+
+ virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant());
+
+ virtual void body_set_ray_pickable(RID p_body, bool p_enable);
+ virtual bool body_is_ray_pickable(RID p_body) const;
+
+ // this function only works on physics process, errors and returns null otherwise
+ virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
+
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL);
+
+ /* SOFT BODY API */
+
+ virtual RID soft_body_create(bool p_init_sleeping = false);
+
+ virtual void soft_body_set_space(RID p_body, RID p_space);
+ virtual RID soft_body_get_space(RID p_body) const;
+
+ virtual void soft_body_set_trimesh_body_shape(RID p_body, PoolVector<int> p_indices, PoolVector<Vector3> p_vertices, int p_triangles_num);
+
+ virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t soft_body_get_collision_layer(RID p_body) const;
+
+ virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask);
+ virtual uint32_t soft_body_get_collision_mask(RID p_body) const;
+
+ virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b);
+ virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b);
+ virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions);
+
+ virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant);
+ virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const;
+
+ virtual void soft_body_set_transform(RID p_body, const Transform &p_transform);
+ virtual Transform soft_body_get_transform(RID p_body) const;
+
+ virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable);
+ virtual bool soft_body_is_ray_pickable(RID p_body) const;
+
+ /* JOINT API */
+
+ virtual JointType joint_get_type(RID p_joint) const;
+
+ virtual void joint_set_solver_priority(RID p_joint, int p_priority);
+ virtual int joint_get_solver_priority(RID p_joint) const;
+
+ virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);
+
+ virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value);
+ virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const;
+
+ virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A);
+ virtual Vector3 pin_joint_get_local_a(RID p_joint) const;
+
+ virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B);
+ virtual Vector3 pin_joint_get_local_b(RID p_joint) const;
+
+ virtual RID joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B);
+ 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);
+
+ virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value);
+ virtual float hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const;
+
+ virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value);
+ virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const;
+
+ /// Reference frame is A
+ virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B);
+
+ virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value);
+ virtual float slider_joint_get_param(RID p_joint, SliderJointParam p_param) const;
+
+ /// Reference frame is A
+ virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B);
+
+ virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value);
+ virtual float cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const;
+
+ /// Reference frame is A
+ virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B);
+
+ virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value);
+ virtual float generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param);
+
+ virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable);
+ virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag);
+
+ /* MISC */
+
+ virtual void free(RID p_rid);
+
+ virtual void set_active(bool p_active) {
+ active = p_active;
+ }
+
+ static bool singleton_isActive() {
+ return static_cast<BulletPhysicsServer *>(get_singleton())->active;
+ }
+
+ bool isActive() {
+ return active;
+ }
+
+ virtual void init();
+ virtual void step(float p_deltaTime);
+ virtual void sync();
+ virtual void flush_queries();
+ virtual void finish();
+
+ virtual int get_process_info(ProcessInfo p_info);
+
+ CollisionObjectBullet *get_collisin_object(RID p_object) const;
+ RigidCollisionObjectBullet *get_rigid_collisin_object(RID p_object) const;
+
+ /// Internal APIs
+public:
+};
+
+#endif
diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp
new file mode 100644
index 0000000000..5010197a78
--- /dev/null
+++ b/modules/bullet/bullet_types_converter.cpp
@@ -0,0 +1,94 @@
+/*************************************************************************/
+/* bullet_types_converter.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+#pragma once
+
+#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, Transform &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(Transform const &inVal, btTransform &outVal) {
+ G_TO_B(inVal.basis, outVal.getBasis());
+ G_TO_B(inVal.origin, outVal.getOrigin());
+}
diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h
new file mode 100644
index 0000000000..ed6a349382
--- /dev/null
+++ b/modules/bullet/bullet_types_converter.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* bullet_types_converter.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "core/math/matrix3.h"
+#include "core/math/transform.h"
+#include "core/math/vector3.h"
+#include "core/typedefs.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, Transform &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(Transform const &inVal, btTransform &outVal);
+
+#endif
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
new file mode 100644
index 0000000000..45cde169b7
--- /dev/null
+++ b/modules/bullet/bullet_utilities.h
@@ -0,0 +1,44 @@
+/*************************************************************************/
+/* bullet_utilities.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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
+
+#pragma once
+
+#define bulletnew(cl) \
+ new cl
+
+#define bulletdelete(cl) \
+ delete cl; \
+ cl = NULL;
+
+#endif
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
new file mode 100644
index 0000000000..91a049b1f3
--- /dev/null
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -0,0 +1,320 @@
+/*************************************************************************/
+/* collision_object_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "btBulletCollisionCommon.h"
+#include "bullet_physics_server.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "shape_bullet.h"
+#include "space_bullet.h"
+
+#define enableDynamicAabbTree true
+#define initialChildCapacity 1
+
+CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {}
+
+void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_transform) {
+ G_TO_B(p_transform, transform);
+}
+void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) {
+ transform = p_transform;
+}
+
+CollisionObjectBullet::CollisionObjectBullet(Type p_type)
+ : RIDBullet(), space(NULL), type(p_type), collisionsEnabled(true), m_isStatic(false), bt_collision_object(NULL), body_scale(1., 1., 1.) {}
+
+CollisionObjectBullet::~CollisionObjectBullet() {
+ // Remove all overlapping
+ for (int i = areasOverlapped.size() - 1; 0 <= i; --i) {
+ areasOverlapped[i]->remove_overlapping_instantly(this);
+ }
+ // not required
+ // areasOverlapped.clear();
+
+ 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])) {
+ G_TO_B(p_new_scale, body_scale);
+ on_body_scale_changed();
+ }
+}
+
+void CollisionObjectBullet::on_body_scale_changed() {
+}
+
+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);
+}
+
+void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
+ exceptions.insert(p_ignoreCollisionObject->get_self());
+ 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());
+ 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 !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object);
+}
+
+void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
+ collisionsEnabled = p_enabled;
+ 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) {
+ 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);
+}
+
+int CollisionObjectBullet::get_godot_object_flags() const {
+ return bt_collision_object->getUserIndex2();
+}
+
+void CollisionObjectBullet::set_transform(const Transform &p_global_transform) {
+
+ btTransform btTrans;
+ Basis decomposed_basis;
+
+ Vector3 decomposed_scale = p_global_transform.get_basis().rotref_posscale_decomposition(decomposed_basis);
+
+ G_TO_B(p_global_transform.get_origin(), btTrans.getOrigin());
+ G_TO_B(decomposed_basis, btTrans.getBasis());
+
+ set_body_scale(decomposed_scale);
+ set_transform__bullet(btTrans);
+}
+
+Transform CollisionObjectBullet::get_transform() const {
+ Transform t;
+ B_TO_G(get_transform__bullet(), t);
+ return t;
+}
+
+void CollisionObjectBullet::set_transform__bullet(const btTransform &p_global_transform) {
+ bt_collision_object->setWorldTransform(p_global_transform);
+}
+
+const btTransform &CollisionObjectBullet::get_transform__bullet() const {
+ return bt_collision_object->getWorldTransform();
+}
+
+RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type)
+ : CollisionObjectBullet(p_type), compoundShape(bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity))) {
+}
+
+RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
+ remove_all_shapes(true);
+ bt_collision_object->setCollisionShape(NULL);
+ bulletdelete(compoundShape);
+}
+
+/* Not used
+void RigidCollisionObjectBullet::_internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) {
+ bool at_least_one_was_changed = false;
+ btTransform old_transf;
+ // Inverse because I need remove the shapes
+ // Fetch all shapes to be sure to remove all shapes
+ for (int i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
+ if (compoundShape->getChildShape(i) == p_old_shape) {
+
+ old_transf = compoundShape->getChildTransform(i);
+ compoundShape->removeChildShapeByIndex(i);
+ compoundShape->addChildShape(old_transf, p_new_shape);
+ at_least_one_was_changed = true;
+ }
+ }
+
+ if (at_least_one_was_changed) {
+ on_shapes_changed();
+ }
+}*/
+
+void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform) {
+ shapes.push_back(ShapeWrapper(p_shape, p_transform, true));
+ p_shape->add_owner(this);
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
+ ShapeWrapper &shp = shapes[p_index];
+ shp.shape->remove_owner(this);
+ p_shape->add_owner(this);
+ shp.shape = p_shape;
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
+ ERR_FAIL_INDEX(p_index, get_shape_count());
+
+ shapes[p_index].set_transform(p_transform);
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::remove_shape(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(i);
+ }
+ }
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::remove_shape(int p_index) {
+ ERR_FAIL_INDEX(p_index, get_shape_count());
+ internal_shape_destroy(p_index);
+ shapes.remove(p_index);
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBody) {
+ // Reverse order required for delete.
+ for (int i = shapes.size() - 1; 0 <= i; --i) {
+ internal_shape_destroy(i, p_permanentlyFromThisBody);
+ }
+ shapes.clear();
+ on_shapes_changed();
+}
+
+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;
+}
+
+Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
+ Transform trs;
+ B_TO_G(shapes[p_index].transform, trs);
+ return trs;
+}
+
+void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_shape) {
+ const int size = shapes.size();
+ for (int i = 0; i < size; ++i) {
+ if (shapes[i].shape == p_shape) {
+ bulletdelete(shapes[i].bt_shape);
+ }
+ }
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::on_shapes_changed() {
+ int i;
+ // Remove all shapes, reverse order for performance reason (Array resize)
+ for (i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
+ compoundShape->removeChildShapeByIndex(i);
+ }
+
+ // Insert all shapes
+ ShapeWrapper *shpWrapper;
+ const int size = shapes.size();
+ for (i = 0; i < size; ++i) {
+ shpWrapper = &shapes[i];
+ if (!shpWrapper->bt_shape) {
+ shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape();
+ }
+ if (shpWrapper->active) {
+ compoundShape->addChildShape(shpWrapper->transform, shpWrapper->bt_shape);
+ } else {
+ compoundShape->addChildShape(shpWrapper->transform, BulletPhysicsServer::get_empty_shape());
+ }
+ }
+
+ compoundShape->setLocalScaling(body_scale);
+ compoundShape->recalculateLocalAabb();
+}
+
+void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
+ shapes[p_index].active = !p_disabled;
+ on_shapes_changed();
+}
+
+bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
+ return !shapes[p_index].active;
+}
+
+void RigidCollisionObjectBullet::on_body_scale_changed() {
+ CollisionObjectBullet::on_body_scale_changed();
+ on_shapes_changed();
+}
+
+void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) {
+ ShapeWrapper &shp = shapes[p_index];
+ shp.shape->remove_owner(this, p_permanentlyFromThisBody);
+ bulletdelete(shp.bt_shape);
+}
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
new file mode 100644
index 0000000000..153b8ea5bc
--- /dev/null
+++ b/modules/bullet/collision_object_bullet.h
@@ -0,0 +1,234 @@
+/*************************************************************************/
+/* collision_object_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btTransform.h"
+#include "core/vset.h"
+#include "object.h"
+#include "shape_owner_bullet.h"
+#include "transform.h"
+#include "vector3.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;
+ btCollisionShape *bt_shape;
+ btTransform transform;
+ bool active;
+
+ ShapeWrapper()
+ : shape(NULL), bt_shape(NULL), active(true) {}
+
+ ShapeWrapper(ShapeBullet *p_shape, const btTransform &p_transform, bool p_active)
+ : shape(p_shape), bt_shape(NULL), active(p_active) {
+ set_transform(p_transform);
+ }
+
+ ShapeWrapper(ShapeBullet *p_shape, const Transform &p_transform, bool p_active)
+ : shape(p_shape), bt_shape(NULL), 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;
+ active = otherShape.active;
+ }
+
+ void set_transform(const Transform &p_transform);
+ void set_transform(const btTransform &p_transform);
+ };
+
+protected:
+ Type type;
+ ObjectID instance_id;
+ uint32_t collisionLayer;
+ uint32_t collisionMask;
+ bool collisionsEnabled;
+ bool m_isStatic;
+ bool ray_pickable;
+ btCollisionObject *bt_collision_object;
+ btVector3 body_scale;
+ SpaceBullet *space;
+
+ 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;
+
+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);
+ virtual void on_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) {
+ 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) {
+ 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; }
+ /// This is an event that is called when a collision checker starts
+ virtual void on_collision_checker_start() = 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);
+
+ /// GodotObjectFlags
+ void set_godot_object_flags(int flags);
+ int get_godot_object_flags() const;
+
+ void set_transform(const Transform &p_global_transform);
+ Transform get_transform() const;
+ virtual void set_transform__bullet(const btTransform &p_global_transform);
+ virtual const btTransform &get_transform__bullet() const;
+};
+
+class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
+protected:
+ /// This is required to combine some shapes together.
+ /// Since Godot allow to have multiple shapes for each body with custom relative location,
+ /// each body will attach the shapes using this class even if there is only one shape.
+ btCompoundShape *compoundShape;
+ Vector<ShapeWrapper> shapes;
+
+public:
+ RigidCollisionObjectBullet(Type p_type);
+ ~RigidCollisionObjectBullet();
+
+ _FORCE_INLINE_ const Vector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; }
+
+ /// This is used to set new shape or replace existing
+ //virtual void _internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) = 0;
+ void add_shape(ShapeBullet *p_shape, const Transform &p_transform = Transform());
+ void set_shape(int p_index, ShapeBullet *p_shape);
+ void set_shape_transform(int p_index, const Transform &p_transform);
+ virtual void remove_shape(ShapeBullet *p_shape);
+ void remove_shape(int p_index);
+ void remove_all_shapes(bool p_permanentlyFromThisBody = false);
+
+ virtual void on_shape_changed(const ShapeBullet *const p_shape);
+ virtual void on_shapes_changed();
+
+ _FORCE_INLINE_ btCompoundShape *get_compound_shape() const { return compoundShape; }
+ int get_shape_count() const;
+ ShapeBullet *get_shape(int p_index) const;
+ btCollisionShape *get_bt_shape(int p_index) const;
+ Transform 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 on_body_scale_changed();
+
+private:
+ void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false);
+};
+
+#endif
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
new file mode 100644
index 0000000000..f6ac40e001
--- /dev/null
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -0,0 +1,111 @@
+/*************************************************************************/
+/* cone_twist_joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "rigid_body_bullet.h"
+
+ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame)
+ : JointBullet() {
+ btTransform btFrameA;
+ G_TO_B(rbAFrame, btFrameA);
+ if (rbB) {
+ btTransform btFrameB;
+ G_TO_B(rbBFrame, 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_angular_only(bool angularOnly) {
+ coneConstraint->setAngularOnly(angularOnly);
+}
+
+void ConeTwistJointBullet::set_limit(real_t _swingSpan1, real_t _swingSpan2, real_t _twistSpan, real_t _softness, real_t _biasFactor, real_t _relaxationFactor) {
+ coneConstraint->setLimit(_swingSpan1, _swingSpan2, _twistSpan, _softness, _biasFactor, _relaxationFactor);
+}
+
+int ConeTwistJointBullet::get_solve_twist_limit() {
+ return coneConstraint->getSolveTwistLimit();
+}
+
+int ConeTwistJointBullet::get_solve_swing_limit() {
+ return coneConstraint->getSolveSwingLimit();
+}
+
+real_t ConeTwistJointBullet::get_twist_limit_sign() {
+ return coneConstraint->getTwistLimitSign();
+}
+
+void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN:
+ coneConstraint->setLimit(5, p_value);
+ coneConstraint->setLimit(4, p_value);
+ break;
+ case PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN:
+ coneConstraint->setLimit(3, p_value);
+ break;
+ case PhysicsServer::CONE_TWIST_JOINT_BIAS:
+ coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), p_value, coneConstraint->getRelaxationFactor());
+ break;
+ case PhysicsServer::CONE_TWIST_JOINT_SOFTNESS:
+ coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), p_value, coneConstraint->getBiasFactor(), coneConstraint->getRelaxationFactor());
+ break;
+ case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
+ coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value);
+ break;
+ default:
+ WARN_PRINT("This parameter is not supported by Bullet engine");
+ }
+}
+
+real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_param) const {
+ switch (p_param) {
+ case PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN:
+ return coneConstraint->getSwingSpan1();
+ case PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN:
+ return coneConstraint->getTwistSpan();
+ case PhysicsServer::CONE_TWIST_JOINT_BIAS:
+ return coneConstraint->getBiasFactor();
+ case PhysicsServer::CONE_TWIST_JOINT_SOFTNESS:
+ return coneConstraint->getLimitSoftness();
+ case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
+ return coneConstraint->getRelaxationFactor();
+ default:
+ WARN_PRINT("This parameter is not supported by Bullet engine");
+ return 0;
+ }
+}
diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h
new file mode 100644
index 0000000000..1ce5ef9826
--- /dev/null
+++ b/modules/bullet/cone_twist_joint_bullet.h
@@ -0,0 +1,58 @@
+/*************************************************************************/
+/* cone_twist_joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 Transform &rbAFrame, const Transform &rbBFrame);
+
+ virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_CONE_TWIST; }
+
+ void set_angular_only(bool angularOnly);
+
+ void set_limit(real_t _swingSpan1, real_t _swingSpan2, real_t _twistSpan, real_t _softness = 0.8f, real_t _biasFactor = 0.3f, real_t _relaxationFactor = 1.0f);
+ int get_solve_twist_limit();
+
+ int get_solve_swing_limit();
+ real_t get_twist_limit_sign();
+
+ void set_param(PhysicsServer::ConeTwistJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer::ConeTwistJointParam p_param) const;
+};
+#endif
diff --git a/modules/bullet/config.py b/modules/bullet/config.py
new file mode 100644
index 0000000000..b00ea18328
--- /dev/null
+++ b/modules/bullet/config.py
@@ -0,0 +1,6 @@
+def can_build(platform):
+ return True
+
+def configure(env):
+ pass
+
diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp
new file mode 100644
index 0000000000..08fc36f274
--- /dev/null
+++ b/modules/bullet/constraint_bullet.cpp
@@ -0,0 +1,50 @@
+/*************************************************************************/
+/* constraint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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()
+ : space(NULL), constraint(NULL) {}
+
+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);
+}
diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h
new file mode 100644
index 0000000000..b528ec6d7b
--- /dev/null
+++ b/modules/bullet/constraint_bullet.h
@@ -0,0 +1,64 @@
+/*************************************************************************/
+/* constraint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "bullet_utilities.h"
+#include "rid_bullet.h"
+
+class RigidBodyBullet;
+class SpaceBullet;
+class btTypedConstraint;
+
+class ConstraintBullet : public RIDBullet {
+
+protected:
+ SpaceBullet *space;
+ btTypedConstraint *constraint;
+
+public:
+ ConstraintBullet();
+
+ virtual void setup(btTypedConstraint *p_constraint);
+ virtual void set_space(SpaceBullet *p_space);
+ virtual void destroy_internal_constraint();
+
+public:
+ virtual ~ConstraintBullet() {
+ bulletdelete(constraint);
+ constraint = NULL;
+ }
+
+ _FORCE_INLINE_ btTypedConstraint *get_bt_constraint() { return constraint; }
+};
+#endif
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
new file mode 100644
index 0000000000..647396c24c
--- /dev/null
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -0,0 +1,241 @@
+/*************************************************************************/
+/* generic_6dof_joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "rigid_body_bullet.h"
+
+Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA)
+ : JointBullet() {
+
+ btTransform btFrameA;
+ G_TO_B(frameInA, btFrameA);
+
+ if (rbB) {
+ btTransform btFrameB;
+ G_TO_B(frameInB, btFrameB);
+
+ sixDOFConstraint = bulletnew(btGeneric6DofConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB, useLinearReferenceFrameA));
+ } else {
+ sixDOFConstraint = bulletnew(btGeneric6DofConstraint(*rbA->get_bt_rigid_body(), btFrameA, useLinearReferenceFrameA));
+ }
+
+ setup(sixDOFConstraint);
+}
+
+Transform Generic6DOFJointBullet::getFrameOffsetA() const {
+ btTransform btTrs = sixDOFConstraint->getFrameOffsetA();
+ Transform gTrs;
+ B_TO_G(btTrs, gTrs);
+ return gTrs;
+}
+
+Transform Generic6DOFJointBullet::getFrameOffsetB() const {
+ btTransform btTrs = sixDOFConstraint->getFrameOffsetB();
+ Transform gTrs;
+ B_TO_G(btTrs, gTrs);
+ return gTrs;
+}
+
+Transform Generic6DOFJointBullet::getFrameOffsetA() {
+ btTransform btTrs = sixDOFConstraint->getFrameOffsetA();
+ Transform gTrs;
+ B_TO_G(btTrs, gTrs);
+ return gTrs;
+}
+
+Transform Generic6DOFJointBullet::getFrameOffsetB() {
+ btTransform btTrs = sixDOFConstraint->getFrameOffsetB();
+ Transform 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, PhysicsServer::G6DOFJointAxisParam p_param, real_t p_value) {
+ ERR_FAIL_INDEX(p_axis, 3);
+ switch (p_param) {
+ case PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_lowerLimit[p_axis] = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_upperLimit[p_axis] = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_limitSoftness = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_restitution = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_damping = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_loLimit = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_hiLimit = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_limitSoftness = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_damping = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_FORCE_LIMIT:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxLimitForce = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_ERP:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity = p_value;
+ break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxLimitForce = p_value;
+ break;
+ default:
+ WARN_PRINT("This parameter is not supported");
+ }
+}
+
+real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param) const {
+ ERR_FAIL_INDEX_V(p_axis, 3, 0.);
+ switch (p_param) {
+ case PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
+ return sixDOFConstraint->getTranslationalLimitMotor()->m_lowerLimit[p_axis];
+ case PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
+ return sixDOFConstraint->getTranslationalLimitMotor()->m_upperLimit[p_axis];
+ case PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS:
+ return sixDOFConstraint->getTranslationalLimitMotor()->m_limitSoftness;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION:
+ return sixDOFConstraint->getTranslationalLimitMotor()->m_restitution;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING:
+ return sixDOFConstraint->getTranslationalLimitMotor()->m_damping;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_loLimit;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_hiLimit;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_limitSoftness;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_damping;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_FORCE_LIMIT:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxLimitForce;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_ERP:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxLimitForce;
+ default:
+ WARN_PRINT("This parameter is not supported");
+ return 0.;
+ }
+}
+
+void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag, bool p_value) {
+ ERR_FAIL_INDEX(p_axis, 3);
+ switch (p_flag) {
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT:
+ if (p_value) {
+ if (!get_flag(p_axis, p_flag)) // avoid overwrite, if limited
+ sixDOFConstraint->setLimit(p_axis, 0, 0); // Limited
+ } else {
+ if (get_flag(p_axis, p_flag)) // avoid overwrite, if free
+ sixDOFConstraint->setLimit(p_axis, 0, -1); // Free
+ }
+ break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: {
+ int angularAxis = 3 + p_axis;
+ if (p_value) {
+ if (!get_flag(p_axis, p_flag)) // avoid overwrite, if Limited
+ sixDOFConstraint->setLimit(angularAxis, 0, 0); // Limited
+ } else {
+ if (get_flag(p_axis, p_flag)) // avoid overwrite, if free
+ sixDOFConstraint->setLimit(angularAxis, 0, -1); // Free
+ }
+ break;
+ }
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR:
+ //sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = p_value;
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor = p_value;
+ break;
+ default:
+ WARN_PRINT("This flag is not supported by Bullet engine");
+ }
+}
+
+bool Generic6DOFJointBullet::get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag) const {
+ ERR_FAIL_INDEX_V(p_axis, 3, false);
+ switch (p_flag) {
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT:
+ return sixDOFConstraint->getTranslationalLimitMotor()->isLimited(p_axis);
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT:
+ return sixDOFConstraint->getRotationalLimitMotor(p_axis)->isLimited();
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR:
+ return //sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] &&
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor;
+ default:
+ WARN_PRINT("This flag is not supported by Bullet engine");
+ return false;
+ }
+}
diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h
new file mode 100644
index 0000000000..0d47b823de
--- /dev/null
+++ b/modules/bullet/generic_6dof_joint_bullet.h
@@ -0,0 +1,65 @@
+/*************************************************************************/
+/* generic_6dof_joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 btGeneric6DofConstraint *sixDOFConstraint;
+
+public:
+ Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA);
+
+ virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_6DOF; }
+
+ Transform getFrameOffsetA() const;
+ Transform getFrameOffsetB() const;
+ Transform getFrameOffsetA();
+ Transform 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, PhysicsServer::G6DOFJointAxisParam p_param, real_t p_value);
+ real_t get_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param) const;
+
+ void set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag, bool p_value);
+ bool get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag) const;
+};
+
+#endif
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
new file mode 100644
index 0000000000..4e4228cc48
--- /dev/null
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -0,0 +1,91 @@
+/*************************************************************************/
+/* godot_collision_configuration.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
+#include "godot_ray_world_algorithm.h"
+
+GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo)
+ : btDefaultCollisionConfiguration(constructionInfo) {
+
+ void *mem = NULL;
+
+ 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);
+ }
+}
diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h
new file mode 100644
index 0000000000..ed99065f8c
--- /dev/null
+++ b/modules/bullet/godot_collision_configuration.h
@@ -0,0 +1,50 @@
+/*************************************************************************/
+/* godot_collision_configuration.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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"
+
+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);
+};
+#endif
diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp
new file mode 100644
index 0000000000..ea75e4eef4
--- /dev/null
+++ b/modules/bullet/godot_collision_dispatcher.cpp
@@ -0,0 +1,54 @@
+/*************************************************************************/
+/* godot_collision_dispatcher.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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) {
+ // Avoide 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) {
+ // Avoide 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
new file mode 100644
index 0000000000..501b2078dd
--- /dev/null
+++ b/modules/bullet/godot_collision_dispatcher.h
@@ -0,0 +1,48 @@
+/*************************************************************************/
+/* godot_collision_dispatcher.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "int_types.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
diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h
new file mode 100644
index 0000000000..5111807394
--- /dev/null
+++ b/modules/bullet/godot_motion_state.h
@@ -0,0 +1,96 @@
+/*************************************************************************/
+/* godot_motion_state.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btMotionState.h"
+#include "rigid_body_bullet.h"
+
+class RigidBodyBullet;
+
+// This clas 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;
+
+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->scratch();
+ }
+
+public:
+ /// Use this function to move kinematic body
+ /// -- or set initial transfom 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
diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp
new file mode 100644
index 0000000000..98daf8398e
--- /dev/null
+++ b/modules/bullet/godot_ray_world_algorithm.cpp
@@ -0,0 +1,104 @@
+/*************************************************************************/
+/* godot_ray_world_algorithm.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
+#include "btRayShape.h"
+#include "collision_object_bullet.h"
+
+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_manifoldPtr(mf),
+ m_ownManifold(false),
+ m_world(world),
+ 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()) {
+ btVector3 ray_normal(to.getOrigin() - ray_transform.getOrigin());
+ ray_normal.normalize();
+ ray_normal *= -1;
+ resultOut->addContactPoint(ray_normal, btResult.m_hitPointWorld, ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1));
+ }
+}
+
+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
new file mode 100644
index 0000000000..15c71b8d7d
--- /dev/null
+++ b/modules/bullet/godot_ray_world_algorithm.h
@@ -0,0 +1,83 @@
+/*************************************************************************/
+/* godot_ray_world_algorithm.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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;
+ bool m_isSwapped;
+
+public:
+ GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *m_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
new file mode 100644
index 0000000000..bc60c9cb6b
--- /dev/null
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -0,0 +1,244 @@
+/*************************************************************************/
+/* godot_result_callbacks.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "bullet_types_converter.h"
+#include "collision_object_bullet.h"
+#include "rigid_body_bullet.h"
+
+bool GodotFilterCallback::test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask) {
+ return body0_collision_layer & body1_collision_mask || body1_collision_layer & body0_collision_mask;
+}
+
+bool GodotFilterCallback::needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const {
+ return GodotFilterCallback::test_collision_filters(proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask, proxy1->m_collisionFilterGroup, proxy1->m_collisionFilterMask);
+}
+
+bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
+ CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
+ if (m_pickRay && gObj->is_ray_pickable()) {
+ return true;
+ } else if (m_exclude->has(gObj->get_self())) {
+ return false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ 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) {
+ CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer());
+
+ PhysicsDirectSpaceState::ShapeResult &result = m_results[count];
+
+ result.shape = convexResult.m_localShapeInfo->m_shapePart;
+ result.rid = gObj->get_self();
+ result.collider_id = gObj->get_instance_id();
+ result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+
+ ++count;
+ return count < m_resultMax;
+}
+
+bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
+ CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
+ if (gObj == m_self_object) {
+ return false;
+ } else {
+ if (m_ignore_areas && gObj->getType() == CollisionObjectBullet::TYPE_AREA) {
+ return false;
+ } else if (m_self_object->has_collision_exception(gObj)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ 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 GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
+ btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
+ m_shapePart = convexResult.m_localShapeInfo->m_shapePart;
+ return res;
+}
+
+bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ 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 GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
+
+ if (cp.getDistance() <= 0) {
+
+ PhysicsDirectSpaceState::ShapeResult &result = m_results[m_count];
+ // Penetrated
+
+ CollisionObjectBullet *colObj;
+ if (m_self_object == colObj0Wrap->getCollisionObject()) {
+ colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
+ result.shape = cp.m_index1;
+ } else {
+ colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
+ result.shape = cp.m_index0;
+ }
+
+ if (colObj)
+ result.collider_id = colObj->get_instance_id();
+ else
+ result.collider_id = 0;
+ result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+ result.rid = colObj->get_self();
+ ++m_count;
+ }
+
+ return m_count < m_resultMax;
+}
+
+bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ 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 GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
+
+ 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 m_count < m_resultMax;
+}
+
+bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
+ const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
+ if (needs) {
+ 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 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());
+ m_result->shape = cp.m_index1;
+ B_TO_G(cp.getPositionWorldOnB(), m_result->point);
+ m_rest_info_bt_point = cp.getPositionWorldOnB();
+ m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
+ } else {
+ colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
+ m_result->shape = cp.m_index0;
+ B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal);
+ m_rest_info_bt_point = cp.getPositionWorldOnA();
+ m_rest_info_collision_object = colObj0Wrap->getCollisionObject();
+ }
+
+ if (colObj)
+ m_result->collider_id = colObj->get_instance_id();
+ else
+ m_result->collider_id = 0;
+ m_result->rid = colObj->get_self();
+
+ m_collided = true;
+ }
+
+ return cp.getDistance();
+}
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
new file mode 100644
index 0000000000..68dff5b12a
--- /dev/null
+++ b/modules/bullet/godot_result_callbacks.h
@@ -0,0 +1,152 @@
+/*************************************************************************/
+/* godot_result_callbacks.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "btBulletDynamicsCommon.h"
+#include "servers/physics_server.h"
+
+class RigidBodyBullet;
+
+/// This class is required to implement custom collision behaviour in the broadphase
+struct GodotFilterCallback : public btOverlapFilterCallback {
+ static bool test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask);
+
+ // 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;
+
+public:
+ GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude)
+ : btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld), m_exclude(p_exclude), m_pickRay(false) {}
+
+ virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
+};
+
+// store all colliding object
+struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback {
+public:
+ PhysicsDirectSpaceState::ShapeResult *m_results;
+ int m_resultMax;
+ int count;
+ const Set<RID> *m_exclude;
+
+ GodotAllConvexResultCallback(PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude)
+ : m_results(p_results), m_exclude(p_exclude), m_resultMax(p_resultMax), count(0) {}
+
+ 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 bool m_ignore_areas;
+
+ GodotKinClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const RigidBodyBullet *p_self_object, bool p_ignore_areas)
+ : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), m_self_object(p_self_object), m_ignore_areas(p_ignore_areas) {}
+
+ virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
+};
+
+struct GodotClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback {
+public:
+ const Set<RID> *m_exclude;
+ int m_shapePart;
+
+ GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude)
+ : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), m_exclude(p_exclude) {}
+
+ 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;
+ PhysicsDirectSpaceState::ShapeResult *m_results;
+ int m_resultMax;
+ int m_count;
+ const Set<RID> *m_exclude;
+
+ GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude)
+ : m_self_object(p_self_object), m_results(p_results), m_exclude(p_exclude), m_resultMax(p_resultMax), m_count(0) {}
+
+ 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;
+ int m_resultMax;
+ int m_count;
+ const Set<RID> *m_exclude;
+
+ GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set<RID> *p_exclude)
+ : m_self_object(p_self_object), m_results(p_results), m_exclude(p_exclude), m_resultMax(p_resultMax), m_count(0) {}
+
+ 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;
+ PhysicsDirectSpaceState::ShapeRestInfo *m_result;
+ bool m_collided;
+ real_t m_min_distance;
+ const btCollisionObject *m_rest_info_collision_object;
+ btVector3 m_rest_info_bt_point;
+ const Set<RID> *m_exclude;
+
+ GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeRestInfo *p_result, const Set<RID> *p_exclude)
+ : m_self_object(p_self_object), m_result(p_result), m_exclude(p_exclude), m_collided(false), m_min_distance(0) {}
+
+ 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);
+};
+
+#endif // GODOT_RESULT_CALLBACKS_H
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
new file mode 100644
index 0000000000..bb70babd99
--- /dev/null
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -0,0 +1,163 @@
+/*************************************************************************/
+/* hinge_joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "rigid_body_bullet.h"
+
+HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB)
+ : JointBullet() {
+ btTransform btFrameA;
+ G_TO_B(frameA, btFrameA);
+
+ if (rbB) {
+ btTransform btFrameB;
+ G_TO_B(frameB, 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, btPivotA);
+ G_TO_B(axisInA, btAxisA);
+
+ if (rbB) {
+ btVector3 btPivotB;
+ btVector3 btAxisB;
+ G_TO_B(pivotInB, btPivotB);
+ G_TO_B(axisInB, 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(PhysicsServer::HingeJointParam p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::HINGE_JOINT_BIAS:
+ if (0 < p_value) {
+ print_line("The Bullet Hinge Joint doesn't support bias, So it's always 0");
+ }
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
+ hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
+ hingeConstraint->setLimit(p_value, hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
+ hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), p_value, hingeConstraint->getLimitRelaxationFactor());
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
+ hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), p_value, hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
+ hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), p_value);
+ break;
+ case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ hingeConstraint->setMotorTargetVelocity(p_value);
+ break;
+ case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ hingeConstraint->setMaxMotorImpulse(p_value);
+ break;
+ default:
+ WARN_PRINTS("The Bullet Hinge Joint doesn't support this parameter: " + itos(p_param) + ", value: " + itos(p_value));
+ }
+}
+
+real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const {
+ switch (p_param) {
+ case PhysicsServer::HINGE_JOINT_BIAS:
+ return 0;
+ break;
+ case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
+ return hingeConstraint->getUpperLimit();
+ case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
+ return hingeConstraint->getLowerLimit();
+ case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
+ return hingeConstraint->getLimitBiasFactor();
+ case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
+ return hingeConstraint->getLimitSoftness();
+ case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
+ return hingeConstraint->getLimitRelaxationFactor();
+ case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ return hingeConstraint->getMotorTargetVelocity();
+ case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ return hingeConstraint->getMaxMotorImpulse();
+ default:
+ WARN_PRINTS("The Bullet Hinge Joint doesn't support this parameter: " + itos(p_param));
+ return 0;
+ }
+}
+
+void HingeJointBullet::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value) {
+ switch (p_flag) {
+ case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT:
+ if (!p_value) {
+ hingeConstraint->setLimit(-Math_PI, Math_PI);
+ }
+ break;
+ case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR:
+ hingeConstraint->enableMotor(p_value);
+ break;
+ }
+}
+
+bool HingeJointBullet::get_flag(PhysicsServer::HingeJointFlag p_flag) const {
+ switch (p_flag) {
+ case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT:
+ return true;
+ case PhysicsServer::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
new file mode 100644
index 0000000000..a78788a5e5
--- /dev/null
+++ b/modules/bullet/hinge_joint_bullet.h
@@ -0,0 +1,54 @@
+/*************************************************************************/
+/* hinge_joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 Transform &frameA, const Transform &frameB);
+ HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB);
+
+ virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_HINGE; }
+
+ real_t get_hinge_angle();
+
+ void set_param(PhysicsServer::HingeJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer::HingeJointParam p_param) const;
+
+ void set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value);
+ bool get_flag(PhysicsServer::HingeJointFlag p_flag) const;
+};
+#endif
diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp
new file mode 100644
index 0000000000..be544f89bf
--- /dev/null
+++ b/modules/bullet/joint_bullet.cpp
@@ -0,0 +1,38 @@
+/*************************************************************************/
+/* joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "joint_bullet.h"
+#include "space_bullet.h"
+
+JointBullet::JointBullet()
+ : ConstraintBullet() {}
+
+JointBullet::~JointBullet() {}
diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h
new file mode 100644
index 0000000000..d47e677502
--- /dev/null
+++ b/modules/bullet/joint_bullet.h
@@ -0,0 +1,49 @@
+/*************************************************************************/
+/* joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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.h"
+
+class RigidBodyBullet;
+class btTypedConstraint;
+
+class JointBullet : public ConstraintBullet {
+
+public:
+ JointBullet();
+ virtual ~JointBullet();
+
+ virtual PhysicsServer::JointType get_type() const = 0;
+};
+#endif
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
new file mode 100644
index 0000000000..cd9e9a4557
--- /dev/null
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -0,0 +1,112 @@
+/*************************************************************************/
+/* pin_joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
+#include "bullet_types_converter.h"
+#include "rigid_body_bullet.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, btPivotA);
+ G_TO_B(p_pos_b, 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(PhysicsServer::PinJointParam p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::PIN_JOINT_BIAS:
+ p2pConstraint->m_setting.m_tau = p_value;
+ break;
+ case PhysicsServer::PIN_JOINT_DAMPING:
+ p2pConstraint->m_setting.m_damping = p_value;
+ break;
+ case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
+ p2pConstraint->m_setting.m_impulseClamp = p_value;
+ break;
+ }
+}
+
+real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
+ switch (p_param) {
+ case PhysicsServer::PIN_JOINT_BIAS:
+ return p2pConstraint->m_setting.m_tau;
+ case PhysicsServer::PIN_JOINT_DAMPING:
+ return p2pConstraint->m_setting.m_damping;
+ case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
+ return p2pConstraint->m_setting.m_impulseClamp;
+ default:
+ WARN_PRINTS("This get parameter is not supported");
+ 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
new file mode 100644
index 0000000000..3a0906bf83
--- /dev/null
+++ b/modules/bullet/pin_joint_bullet.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* pin_joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_PIN; }
+
+ void set_param(PhysicsServer::PinJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer::PinJointParam p_param) const;
+
+ void setPivotInA(const Vector3 &p_pos);
+ void setPivotInB(const Vector3 &p_pos);
+
+ Vector3 getPivotInA();
+ Vector3 getPivotInB();
+};
+#endif
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
new file mode 100644
index 0000000000..1e697e7443
--- /dev/null
+++ b/modules/bullet/register_types.cpp
@@ -0,0 +1,47 @@
+/*************************************************************************/
+/* register_types.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "class_db.h"
+
+PhysicsServer *_createBulletPhysicsCallback() {
+ return memnew(BulletPhysicsServer);
+}
+
+void register_bullet_types() {
+
+ PhysicsServerManager::register_server("Bullet", &_createBulletPhysicsCallback);
+ PhysicsServerManager::set_default_server("Bullet", 1);
+}
+
+void unregister_bullet_types() {
+}
diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h
new file mode 100644
index 0000000000..ca0683fa3b
--- /dev/null
+++ b/modules/bullet/register_types.h
@@ -0,0 +1,37 @@
+/*************************************************************************/
+/* register_types.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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
diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h
new file mode 100644
index 0000000000..da7517f246
--- /dev/null
+++ b/modules/bullet/rid_bullet.h
@@ -0,0 +1,50 @@
+/*************************************************************************/
+/* rid_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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/rid.h"
+
+class BulletPhysicsServer;
+
+class RIDBullet : public RID_Data {
+ RID self;
+ BulletPhysicsServer *physicsServer;
+
+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(BulletPhysicsServer *p_physicsServer) { physicsServer = p_physicsServer; }
+ _FORCE_INLINE_ BulletPhysicsServer *get_physics_server() const { return physicsServer; }
+};
+#endif
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
new file mode 100644
index 0000000000..98ae82bc5f
--- /dev/null
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -0,0 +1,999 @@
+/*************************************************************************/
+/* body_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "BulletCollision/CollisionShapes/btConvexPointCloudShape.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "btBulletCollisionCommon.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 <assert.h>
+
+BulletPhysicsDirectBodyState *BulletPhysicsDirectBodyState::singleton = NULL;
+
+Vector3 BulletPhysicsDirectBodyState::get_total_gravity() const {
+ Vector3 gVec;
+ B_TO_G(body->btBody->getGravity(), gVec);
+ return gVec;
+}
+
+float BulletPhysicsDirectBodyState::get_total_angular_damp() const {
+ return body->btBody->getAngularDamping();
+}
+
+float BulletPhysicsDirectBodyState::get_total_linear_damp() const {
+ return body->btBody->getLinearDamping();
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_center_of_mass() const {
+ Vector3 gVec;
+ B_TO_G(body->btBody->getCenterOfMassPosition(), gVec);
+ return gVec;
+}
+
+Basis BulletPhysicsDirectBodyState::get_principal_inertia_axes() const {
+ return Basis();
+}
+
+float BulletPhysicsDirectBodyState::get_inverse_mass() const {
+ return body->btBody->getInvMass();
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_inverse_inertia() const {
+ Vector3 gVec;
+ B_TO_G(body->btBody->getInvInertiaDiagLocal(), gVec);
+ return gVec;
+}
+
+Basis BulletPhysicsDirectBodyState::get_inverse_inertia_tensor() const {
+ Basis gInertia;
+ B_TO_G(body->btBody->getInvInertiaTensorWorld(), gInertia);
+ return gInertia;
+}
+
+void BulletPhysicsDirectBodyState::set_linear_velocity(const Vector3 &p_velocity) {
+ body->set_linear_velocity(p_velocity);
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_linear_velocity() const {
+ return body->get_linear_velocity();
+}
+
+void BulletPhysicsDirectBodyState::set_angular_velocity(const Vector3 &p_velocity) {
+ body->set_angular_velocity(p_velocity);
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_angular_velocity() const {
+ return body->get_angular_velocity();
+}
+
+void BulletPhysicsDirectBodyState::set_transform(const Transform &p_transform) {
+ body->set_transform(p_transform);
+}
+
+Transform BulletPhysicsDirectBodyState::get_transform() const {
+ return body->get_transform();
+}
+
+void BulletPhysicsDirectBodyState::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
+ body->apply_force(p_force, p_pos);
+}
+
+void BulletPhysicsDirectBodyState::apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) {
+ body->apply_impulse(p_pos, p_j);
+}
+
+void BulletPhysicsDirectBodyState::apply_torque_impulse(const Vector3 &p_j) {
+ body->apply_torque_impulse(p_j);
+}
+
+void BulletPhysicsDirectBodyState::set_sleep_state(bool p_enable) {
+ body->set_activation_state(p_enable);
+}
+
+bool BulletPhysicsDirectBodyState::is_sleeping() const {
+ return !body->is_active();
+}
+
+int BulletPhysicsDirectBodyState::get_contact_count() const {
+ return body->collisionsCount;
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_contact_local_position(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].hitLocalLocation;
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_contact_local_normal(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].hitNormal;
+}
+
+int BulletPhysicsDirectBodyState::get_contact_local_shape(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].local_shape;
+}
+
+RID BulletPhysicsDirectBodyState::get_contact_collider(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].otherObject->get_self();
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_contact_collider_position(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].hitWorldLocation;
+}
+
+ObjectID BulletPhysicsDirectBodyState::get_contact_collider_id(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].otherObject->get_instance_id();
+}
+
+int BulletPhysicsDirectBodyState::get_contact_collider_shape(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].other_object_shape;
+}
+
+Vector3 BulletPhysicsDirectBodyState::get_contact_collider_velocity_at_position(int p_contact_idx) const {
+ RigidBodyBullet::CollisionData &colDat = body->collisions[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;
+}
+
+PhysicsDirectSpaceState *BulletPhysicsDirectBodyState::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;
+
+ for (int i = shapes_count - 1; 0 <= i; --i) {
+ shape_wrapper = &shapes_wrappers[i];
+ if (!shape_wrapper->active) {
+ continue;
+ }
+ shapes[i].transform = shape_wrapper->transform;
+
+ btConvexShape *&kin_shape_ref = shapes[i].shape;
+
+ switch (shape_wrapper->shape->get_type()) {
+ case PhysicsServer::SHAPE_SPHERE: {
+ SphereShapeBullet *sphere = static_cast<SphereShapeBullet *>(shape_wrapper->shape);
+ kin_shape_ref = ShapeBullet::create_shape_sphere(sphere->get_radius() * owner->body_scale[0] + safe_margin);
+ break;
+ }
+ case PhysicsServer::SHAPE_BOX: {
+ BoxShapeBullet *box = static_cast<BoxShapeBullet *>(shape_wrapper->shape);
+ kin_shape_ref = ShapeBullet::create_shape_box((box->get_half_extents() * owner->body_scale) + btVector3(safe_margin, safe_margin, safe_margin));
+ break;
+ }
+ case PhysicsServer::SHAPE_CAPSULE: {
+ CapsuleShapeBullet *capsule = static_cast<CapsuleShapeBullet *>(shape_wrapper->shape);
+ kin_shape_ref = ShapeBullet::create_shape_capsule(capsule->get_radius() * owner->body_scale[0] + safe_margin, capsule->get_height() * owner->body_scale[1] + safe_margin);
+ break;
+ }
+ case PhysicsServer::SHAPE_CONVEX_POLYGON: {
+ ConvexPolygonShapeBullet *godot_convex = static_cast<ConvexPolygonShapeBullet *>(shape_wrapper->shape);
+ kin_shape_ref = ShapeBullet::create_shape_convex(godot_convex->vertices);
+ kin_shape_ref->setLocalScaling(owner->body_scale + btVector3(safe_margin, safe_margin, safe_margin));
+ break;
+ }
+ case PhysicsServer::SHAPE_RAY: {
+ RayShapeBullet *godot_ray = static_cast<RayShapeBullet *>(shape_wrapper->shape);
+ kin_shape_ref = ShapeBullet::create_shape_ray(godot_ray->length * owner->body_scale[1] + safe_margin);
+ break;
+ }
+ default:
+ WARN_PRINT("This shape is not supported to be kinematic!");
+ kin_shape_ref = NULL;
+ }
+ }
+}
+
+void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
+ for (int i = shapes.size() - 1; 0 <= i; --i) {
+ if (shapes[i].shape) {
+ bulletdelete(shapes[i].shape);
+ }
+ }
+ shapes.resize(new_size);
+}
+
+RigidBodyBullet::RigidBodyBullet()
+ : RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY),
+ kinematic_utilities(NULL),
+ gravity_scale(1),
+ mass(1),
+ linearDamp(0),
+ angularDamp(0),
+ can_sleep(true),
+ force_integration_callback(NULL),
+ isTransformChanged(false),
+ maxCollisionsDetection(0),
+ collisionsCount(0),
+ maxAreasWhereIam(10),
+ areaWhereIamCount(0),
+ countGravityPointSpaces(0),
+ isScratchedSpaceOverrideModificator(false) {
+
+ godotMotionState = bulletnew(GodotMotionState(this));
+
+ // Initial properties
+ const btVector3 localInertia(0, 0, 0);
+ btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, compoundShape, localInertia);
+
+ btBody = bulletnew(btRigidBody(cInfo));
+ setupBulletCollisionObject(btBody);
+
+ set_mode(PhysicsServer::BODY_MODE_RIGID);
+ set_axis_lock(PhysicsServer::BODY_AXIS_LOCK_DISABLED);
+
+ areasWhereIam.resize(maxAreasWhereIam);
+ for (int i = areasWhereIam.size() - 1; 0 <= i; --i) {
+ areasWhereIam[i] = NULL;
+ }
+}
+
+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));
+}
+
+void RigidBodyBullet::destroy_kinematic_utilities() {
+ if (kinematic_utilities) {
+ memdelete(kinematic_utilities);
+ kinematic_utilities = NULL;
+ }
+}
+
+void RigidBodyBullet::reload_body() {
+ if (space) {
+ space->remove_rigid_body(this);
+ space->add_rigid_body(this);
+ }
+}
+
+void RigidBodyBullet::set_space(SpaceBullet *p_space) {
+ // Clear the old space if there is one
+ if (space) {
+ isTransformChanged = false;
+
+ // Remove all eventual constraints
+ assert_no_constraints();
+
+ // 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 isTransformChanged is necessary in order to call integrated forces only when the first transform is sent
+ if (btBody->isActive() && force_integration_callback && isTransformChanged) {
+
+ BulletPhysicsDirectBodyState *bodyDirect = BulletPhysicsDirectBodyState::get_singleton(this);
+
+ Variant variantBodyDirect = bodyDirect;
+
+ Object *obj = ObjectDB::get_instance(force_integration_callback->id);
+ if (!obj) {
+ // Remove integration callback
+ set_force_integration_callback(0, StringName());
+ } else {
+ const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata };
+
+ Variant::CallError responseCallError;
+ int argc = (force_integration_callback->udata.get_type() == Variant::NIL) ? 1 : 2;
+ obj->call(force_integration_callback->method, vp, argc, 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());
+}
+
+void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
+
+ if (force_integration_callback) {
+ memdelete(force_integration_callback);
+ force_integration_callback = NULL;
+ }
+
+ if (p_id != 0) {
+ force_integration_callback = memnew(ForceIntegrationCallback);
+ force_integration_callback->id = p_id;
+ force_integration_callback->method = p_method;
+ force_integration_callback->udata = p_udata;
+ }
+}
+
+void RigidBodyBullet::scratch() {
+ isTransformChanged = true;
+}
+
+void RigidBodyBullet::scratch_space_override_modificator() {
+ isScratchedSpaceOverrideModificator = true;
+}
+
+void RigidBodyBullet::on_collision_filters_change() {
+ if (space) {
+ space->reload_collision_filters(this);
+ }
+}
+
+void RigidBodyBullet::on_collision_checker_start() {
+ collisionsCount = 0;
+}
+
+bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, int p_other_shape_index, int p_local_shape_index) {
+
+ if (collisionsCount >= maxCollisionsDetection) {
+ return false;
+ }
+
+ CollisionData &cd = collisions[collisionsCount];
+ cd.hitLocalLocation = p_hitLocalLocation;
+ cd.otherObject = p_otherObject;
+ cd.hitWorldLocation = p_hitWorldLocation;
+ cd.hitNormal = p_hitNormal;
+ cd.other_object_shape = p_other_shape_index;
+ cd.local_shape = p_local_shape_index;
+
+ ++collisionsCount;
+ return true;
+}
+
+void RigidBodyBullet::assert_no_constraints() {
+ if (btBody->getNumConstraintRefs()) {
+ WARN_PRINT("A body with a joints is destroyed. Please check the implementation in order to destroy the joint before the body.");
+ }
+ /*for(int i = btBody->getNumConstraintRefs()-1; 0<=i; --i){
+ btTypedConstraint* btConst = btBody->getConstraintRef(i);
+ JointBullet* joint = static_cast<JointBullet*>( btConst->getUserConstraintPtr() );
+ space->removeConstraint(joint);
+ }*/
+}
+
+void RigidBodyBullet::set_activation_state(bool p_active) {
+ if (p_active) {
+ btBody->setActivationState(ACTIVE_TAG);
+ } else {
+ btBody->setActivationState(WANTS_DEACTIVATION);
+ }
+}
+
+bool RigidBodyBullet::is_active() const {
+ return btBody->isActive();
+}
+
+void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::BODY_PARAM_BOUNCE:
+ btBody->setRestitution(p_value);
+ break;
+ case PhysicsServer::BODY_PARAM_FRICTION:
+ btBody->setFriction(p_value);
+ break;
+ case PhysicsServer::BODY_PARAM_MASS: {
+ ERR_FAIL_COND(p_value < 0);
+ mass = p_value;
+ _internal_set_mass(p_value);
+ break;
+ }
+ case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
+ linearDamp = p_value;
+ btBody->setDamping(linearDamp, angularDamp);
+ break;
+ case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
+ angularDamp = p_value;
+ btBody->setDamping(linearDamp, angularDamp);
+ break;
+ case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
+ gravity_scale = p_value;
+ /// The Bullet gravity will be is set by reload_space_override_modificator
+ scratch_space_override_modificator();
+ break;
+ default:
+ WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value));
+ }
+}
+
+real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const {
+ switch (p_param) {
+ case PhysicsServer::BODY_PARAM_BOUNCE:
+ return btBody->getRestitution();
+ case PhysicsServer::BODY_PARAM_FRICTION:
+ return btBody->getFriction();
+ case PhysicsServer::BODY_PARAM_MASS: {
+ const btScalar invMass = btBody->getInvMass();
+ return 0 == invMass ? 0 : 1 / invMass;
+ }
+ case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
+ return linearDamp;
+ case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
+ return angularDamp;
+ case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
+ return gravity_scale;
+ default:
+ WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet");
+ return 0;
+ }
+}
+
+void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
+ // This is necessary to block force_integration untile next move
+ isTransformChanged = false;
+ destroy_kinematic_utilities();
+ // The mode change is relevant to its mass
+ switch (p_mode) {
+ case PhysicsServer::BODY_MODE_KINEMATIC:
+ mode = PhysicsServer::BODY_MODE_KINEMATIC;
+ set_axis_lock(axis_lock); // Reload axis lock
+ _internal_set_mass(0);
+ init_kinematic_utilities();
+ break;
+ case PhysicsServer::BODY_MODE_STATIC:
+ mode = PhysicsServer::BODY_MODE_STATIC;
+ set_axis_lock(axis_lock); // Reload axis lock
+ _internal_set_mass(0);
+ break;
+ case PhysicsServer::BODY_MODE_RIGID: {
+ mode = PhysicsServer::BODY_MODE_RIGID;
+ set_axis_lock(axis_lock); // Reload axis lock
+ _internal_set_mass(0 == mass ? 1 : mass);
+ break;
+ }
+ case PhysicsServer::BODY_MODE_CHARACTER: {
+ mode = PhysicsServer::BODY_MODE_CHARACTER;
+ set_axis_lock(axis_lock); // Reload axis lock
+ _internal_set_mass(0 == mass ? 1 : mass);
+ break;
+ }
+ }
+
+ btBody->setAngularVelocity(btVector3(0, 0, 0));
+ btBody->setLinearVelocity(btVector3(0, 0, 0));
+}
+PhysicsServer::BodyMode RigidBodyBullet::get_mode() const {
+ return mode;
+}
+
+void RigidBodyBullet::set_state(PhysicsServer::BodyState p_state, const Variant &p_variant) {
+
+ switch (p_state) {
+ case PhysicsServer::BODY_STATE_TRANSFORM:
+ set_transform(p_variant);
+ break;
+ case PhysicsServer::BODY_STATE_LINEAR_VELOCITY:
+ set_linear_velocity(p_variant);
+ break;
+ case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY:
+ set_angular_velocity(p_variant);
+ break;
+ case PhysicsServer::BODY_STATE_SLEEPING:
+ set_activation_state(!bool(p_variant));
+ break;
+ case PhysicsServer::BODY_STATE_CAN_SLEEP:
+ can_sleep = bool(p_variant);
+ if (!can_sleep) {
+ // Can't sleep
+ btBody->forceActivationState(DISABLE_DEACTIVATION);
+ }
+ break;
+ }
+}
+
+Variant RigidBodyBullet::get_state(PhysicsServer::BodyState p_state) const {
+ switch (p_state) {
+ case PhysicsServer::BODY_STATE_TRANSFORM:
+ return get_transform();
+ case PhysicsServer::BODY_STATE_LINEAR_VELOCITY:
+ return get_linear_velocity();
+ case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY:
+ return get_angular_velocity();
+ case PhysicsServer::BODY_STATE_SLEEPING:
+ return !is_active();
+ case PhysicsServer::BODY_STATE_CAN_SLEEP:
+ return can_sleep;
+ default:
+ WARN_PRINTS("This state " + itos(p_state) + " is not supported by Bullet");
+ return Variant();
+ }
+}
+
+void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) {
+ btVector3 btImpu;
+ G_TO_B(p_impulse, btImpu);
+ btBody->activate();
+ btBody->applyCentralImpulse(btImpu);
+}
+
+void RigidBodyBullet::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
+ btVector3 btImpu;
+ btVector3 btPos;
+ G_TO_B(p_impulse, btImpu);
+ G_TO_B(p_pos, btPos);
+ btBody->activate();
+ btBody->applyImpulse(btImpu, btPos);
+}
+
+void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) {
+ btVector3 btImp;
+ G_TO_B(p_impulse, btImp);
+ btBody->activate();
+ btBody->applyTorqueImpulse(btImp);
+}
+
+void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_pos) {
+ btVector3 btForce;
+ btVector3 btPos;
+ G_TO_B(p_force, btForce);
+ G_TO_B(p_pos, btPos);
+ btBody->activate();
+ btBody->applyForce(btForce, btPos);
+}
+
+void RigidBodyBullet::apply_central_force(const Vector3 &p_force) {
+ btVector3 btForce;
+ G_TO_B(p_force, btForce);
+ btBody->activate();
+ btBody->applyCentralForce(btForce);
+}
+
+void RigidBodyBullet::apply_torque(const Vector3 &p_torque) {
+ btVector3 btTorq;
+ G_TO_B(p_torque, btTorq);
+ btBody->activate();
+ btBody->applyTorque(btTorq);
+}
+
+void RigidBodyBullet::set_applied_force(const Vector3 &p_force) {
+ btVector3 btVec = btBody->getTotalTorque();
+
+ 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();
+
+ 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(PhysicsServer::BodyAxisLock p_lock) {
+ axis_lock = p_lock;
+
+ if (PhysicsServer::BODY_AXIS_LOCK_DISABLED == axis_lock) {
+ btBody->setLinearFactor(btVector3(1., 1., 1.));
+ btBody->setAngularFactor(btVector3(1., 1., 1.));
+ } else if (PhysicsServer::BODY_AXIS_LOCK_X == axis_lock) {
+ btBody->setLinearFactor(btVector3(0., 1., 1.));
+ btBody->setAngularFactor(btVector3(1., 0., 0.));
+ } else if (PhysicsServer::BODY_AXIS_LOCK_Y == axis_lock) {
+ btBody->setLinearFactor(btVector3(1., 0., 1.));
+ btBody->setAngularFactor(btVector3(0., 1., 0.));
+ } else if (PhysicsServer::BODY_AXIS_LOCK_Z == axis_lock) {
+ btBody->setLinearFactor(btVector3(1., 1., 0.));
+ btBody->setAngularFactor(btVector3(0., 0., 1.));
+ }
+
+ if (PhysicsServer::BODY_MODE_CHARACTER == mode) {
+ /// When character lock angular
+ btBody->setAngularFactor(btVector3(0., 0., 0.));
+ }
+}
+
+PhysicsServer::BodyAxisLock RigidBodyBullet::get_axis_lock() const {
+ btVector3 vec = btBody->getLinearFactor();
+ if (0. == vec.x()) {
+ return PhysicsServer::BODY_AXIS_LOCK_X;
+ } else if (0. == vec.y()) {
+ return PhysicsServer::BODY_AXIS_LOCK_Y;
+ } else if (0. == vec.z()) {
+ return PhysicsServer::BODY_AXIS_LOCK_Z;
+ } else {
+ return PhysicsServer::BODY_AXIS_LOCK_DISABLED;
+ }
+}
+
+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(1);
+
+ /// Calculate using the rule writte 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 dimentions 1 meter, try 0.2
+ btVector3 center;
+ btScalar radius;
+ 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);
+ 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);
+ 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 == PhysicsServer::BODY_MODE_KINEMATIC) {
+ // The kinematic use MotionState class
+ godotMotionState->moveBody(p_global_transform);
+ }
+ btBody->setWorldTransform(p_global_transform);
+}
+
+const btTransform &RigidBodyBullet::get_transform__bullet() const {
+ if (is_static()) {
+
+ return RigidCollisionObjectBullet::get_transform__bullet();
+ } else {
+
+ return godotMotionState->getCurrentWorldTransform();
+ }
+}
+
+void RigidBodyBullet::on_shapes_changed() {
+ RigidCollisionObjectBullet::on_shapes_changed();
+
+ const btScalar invMass = btBody->getInvMass();
+ const btScalar mass = invMass == 0 ? 0 : 1 / invMass;
+
+ btVector3 inertia;
+ btBody->getCollisionShape()->calculateLocalInertia(mass, inertia);
+ btBody->setMassProps(mass, inertia);
+ btBody->updateInertiaTensor();
+
+ reload_kinematic_shapes();
+
+ 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 (NULL == areasWhereIam[i]) {
+ // This area has the highest priority
+ areasWhereIam[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 = i; j < areaWhereIamCount; ++j) {
+ areasWhereIam[j + 1] = areasWhereIam[j];
+ }
+ areasWhereIam[i] = p_area;
+ break;
+ }
+ }
+ }
+ if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
+ scratch_space_override_modificator();
+ }
+
+ if (p_area->is_spOv_gravityPoint()) {
+ ++countGravityPointSpaces;
+ assert(0 < countGravityPointSpaces);
+ }
+}
+
+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 fount, just shift down all elements
+ for (int j = i; j < areaWhereIamCount; ++j) {
+ areasWhereIam[j] = areasWhereIam[j + 1];
+ }
+ wasTheAreaFound = true;
+ break;
+ }
+ }
+ if (wasTheAreaFound) {
+ if (p_area->is_spOv_gravityPoint()) {
+ --countGravityPointSpaces;
+ assert(0 <= countGravityPointSpaces);
+ }
+
+ --areaWhereIamCount;
+ areasWhereIam[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe
+ if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
+ scratch_space_override_modificator();
+ }
+ }
+}
+
+void RigidBodyBullet::reload_space_override_modificator() {
+
+ Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude());
+ real_t newLinearDamp(linearDamp);
+ real_t newAngularDamp(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);
+
+ int countCombined(0);
+ for (int i = areaWhereIamCount - 1; 0 <= i; --i) {
+
+ currentArea = areasWhereIam[i];
+
+ if (PhysicsServer::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 PhysicsServer::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 PhysicsServer::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();
+ ++countCombined;
+ break;
+ case PhysicsServer::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();
+ ++countCombined;
+ goto endAreasCycle;
+ case PhysicsServer::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();
+ countCombined = 1;
+ goto endAreasCycle;
+ case PhysicsServer::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();
+ countCombined = 1;
+ break;
+ }
+ }
+endAreasCycle:
+
+ if (1 < countCombined) {
+ newGravity /= countCombined;
+ newLinearDamp /= countCombined;
+ newAngularDamp /= countCombined;
+ }
+
+ 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::_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) {
+
+ ERR_FAIL_COND(PhysicsServer::BODY_MODE_RIGID != mode && PhysicsServer::BODY_MODE_CHARACTER != mode);
+
+ m_isStatic = false;
+ compoundShape->calculateLocalInertia(p_mass, localInertia);
+
+ if (PhysicsServer::BODY_MODE_RIGID == 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 {
+
+ ERR_FAIL_COND(PhysicsServer::BODY_MODE_STATIC != mode && PhysicsServer::BODY_MODE_KINEMATIC != mode);
+
+ m_isStatic = true;
+ if (PhysicsServer::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
new file mode 100644
index 0000000000..ab3c3e58b2
--- /dev/null
+++ b/modules/bullet/rigid_body_bullet.h
@@ -0,0 +1,302 @@
+/*************************************************************************/
+/* body_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 BODYBULLET_H
+#define BODYBULLET_H
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "LinearMath/btTransform.h"
+#include "collision_object_bullet.h"
+#include "space_bullet.h"
+
+class AreaBullet;
+class SpaceBullet;
+class btRigidBody;
+class GodotMotionState;
+class BulletPhysicsDirectBodyState;
+
+/// This class could be used in multi thread with few changes but currently
+/// is setted 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 BulletPhysicsServer and is held by the "singleton" variable of this class
+/// Each time something require it, the body must be setted again.
+class BulletPhysicsDirectBodyState : public PhysicsDirectBodyState {
+ GDCLASS(BulletPhysicsDirectBodyState, PhysicsDirectBodyState)
+
+ static BulletPhysicsDirectBodyState *singleton;
+
+public:
+ /// This class avoid the creation of more object of this class
+ static void initSingleton() {
+ if (!singleton) {
+ singleton = memnew(BulletPhysicsDirectBodyState);
+ }
+ }
+
+ static void destroySingleton() {
+ memdelete(singleton);
+ singleton = NULL;
+ }
+
+ static void singleton_setDeltaTime(real_t p_deltaTime) {
+ singleton->deltaTime = p_deltaTime;
+ }
+
+ static BulletPhysicsDirectBodyState *get_singleton(RigidBodyBullet *p_body) {
+ singleton->body = p_body;
+ return singleton;
+ }
+
+public:
+ RigidBodyBullet *body;
+ real_t deltaTime;
+
+private:
+ BulletPhysicsDirectBodyState() {}
+
+public:
+ virtual Vector3 get_total_gravity() const;
+ virtual float get_total_angular_damp() const;
+ virtual float get_total_linear_damp() const;
+
+ virtual Vector3 get_center_of_mass() const;
+ virtual Basis get_principal_inertia_axes() const;
+ // get the mass
+ virtual float get_inverse_mass() const;
+ // get density of this body space
+ virtual Vector3 get_inverse_inertia() const;
+ // get density of this body space
+ virtual Basis get_inverse_inertia_tensor() const;
+
+ virtual void set_linear_velocity(const Vector3 &p_velocity);
+ virtual Vector3 get_linear_velocity() const;
+
+ virtual void set_angular_velocity(const Vector3 &p_velocity);
+ virtual Vector3 get_angular_velocity() const;
+
+ virtual void set_transform(const Transform &p_transform);
+ virtual Transform get_transform() const;
+
+ virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos);
+ virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j);
+ virtual void apply_torque_impulse(const Vector3 &p_j);
+
+ virtual void set_sleep_state(bool p_enable);
+ virtual bool is_sleeping() const;
+
+ virtual int get_contact_count() const;
+
+ virtual Vector3 get_contact_local_position(int p_contact_idx) const;
+ virtual Vector3 get_contact_local_normal(int p_contact_idx) const;
+ virtual int get_contact_local_shape(int p_contact_idx) const;
+
+ virtual RID get_contact_collider(int p_contact_idx) const;
+ virtual Vector3 get_contact_collider_position(int p_contact_idx) const;
+ virtual ObjectID get_contact_collider_id(int p_contact_idx) const;
+ virtual int get_contact_collider_shape(int p_contact_idx) const;
+ virtual Vector3 get_contact_collider_velocity_at_position(int p_contact_idx) const;
+
+ virtual real_t get_step() const { return deltaTime; }
+ virtual void integrate_forces() {
+ // Skip the execution of this function
+ }
+
+ virtual PhysicsDirectSpaceState *get_space_state();
+};
+
+class RigidBodyBullet : public RigidCollisionObjectBullet {
+
+public:
+ struct CollisionData {
+ RigidBodyBullet *otherObject;
+ int other_object_shape;
+ int local_shape;
+ Vector3 hitLocalLocation;
+ Vector3 hitWorldLocation;
+ Vector3 hitNormal;
+ };
+
+ struct ForceIntegrationCallback {
+ ObjectID id;
+ StringName method;
+ Variant udata;
+ };
+
+ /// Used to hold shapes
+ struct KinematicShape {
+ class btConvexShape *shape;
+ btTransform transform;
+
+ KinematicShape()
+ : shape(NULL) {}
+ const bool is_active() const { return shape; }
+ };
+
+ struct KinematicUtilities {
+ RigidBodyBullet *owner;
+ 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 BulletPhysicsDirectBodyState;
+
+ // This is required only for Kinematic movement
+ KinematicUtilities *kinematic_utilities;
+
+ PhysicsServer::BodyMode mode;
+ PhysicsServer::BodyAxisLock axis_lock;
+ GodotMotionState *godotMotionState;
+ btRigidBody *btBody;
+ real_t mass;
+ real_t gravity_scale;
+ real_t linearDamp;
+ real_t angularDamp;
+ bool can_sleep;
+
+ Vector<CollisionData> collisions;
+ // these parameters are used to avoid vector resize
+ int maxCollisionsDetection;
+ int collisionsCount;
+
+ Vector<AreaBullet *> areasWhereIam;
+ // these parameters are used to avoid vector resize
+ int maxAreasWhereIam;
+ int areaWhereIamCount;
+ // Used to know if the area is used as gravity point
+ int countGravityPointSpaces;
+ bool isScratchedSpaceOverrideModificator;
+
+ bool isTransformChanged;
+
+ ForceIntegrationCallback *force_integration_callback;
+
+public:
+ RigidBodyBullet();
+ ~RigidBodyBullet();
+
+ void init_kinematic_utilities();
+ void destroy_kinematic_utilities();
+ _FORCE_INLINE_ class KinematicUtilities *get_kinematic_utilities() const { return kinematic_utilities; }
+
+ _FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
+
+ virtual void reload_body();
+ virtual void set_space(SpaceBullet *p_space);
+
+ virtual void dispatch_callbacks();
+ void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
+ void scratch();
+ void scratch_space_override_modificator();
+
+ virtual void on_collision_filters_change();
+ virtual void on_collision_checker_start();
+ void set_max_collisions_detection(int p_maxCollisionsDetection) {
+ maxCollisionsDetection = p_maxCollisionsDetection;
+ collisions.resize(p_maxCollisionsDetection);
+ collisionsCount = 0;
+ }
+ 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, int p_other_shape_index, int p_local_shape_index);
+
+ void assert_no_constraints();
+
+ void set_activation_state(bool p_active);
+ bool is_active() const;
+
+ void set_param(PhysicsServer::BodyParameter p_param, real_t);
+ real_t get_param(PhysicsServer::BodyParameter p_param) const;
+
+ void set_mode(PhysicsServer::BodyMode p_mode);
+ PhysicsServer::BodyMode get_mode() const;
+
+ void set_state(PhysicsServer::BodyState p_state, const Variant &p_variant);
+ Variant get_state(PhysicsServer::BodyState p_state) const;
+
+ void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
+ void apply_central_impulse(const Vector3 &p_force);
+ void apply_torque_impulse(const Vector3 &p_impulse);
+
+ void apply_force(const Vector3 &p_force, const Vector3 &p_pos);
+ void apply_central_force(const Vector3 &p_force);
+ void apply_torque(const Vector3 &p_force);
+
+ 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(PhysicsServer::BodyAxisLock p_lock);
+ PhysicsServer::BodyAxisLock get_axis_lock() const;
+
+ /// Doc:
+ /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=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 on_shapes_changed();
+
+ 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();
+
+private:
+ void _internal_set_mass(real_t p_mass);
+};
+
+#endif
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
new file mode 100644
index 0000000000..49150484d9
--- /dev/null
+++ b/modules/bullet/shape_bullet.cpp
@@ -0,0 +1,435 @@
+/*************************************************************************/
+/* shape_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/CollisionShapes/btConvexPointCloudShape.h"
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
+#include "btBulletCollisionCommon.h"
+#include "btRayShape.h"
+#include "bullet_physics_server.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "shape_owner_bullet.h"
+
+ShapeBullet::ShapeBullet() {}
+
+ShapeBullet::~ShapeBullet() {}
+
+btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const {
+ p_btShape->setUserPointer(const_cast<ShapeBullet *>(this));
+ return p_btShape;
+}
+
+void ShapeBullet::notifyShapeChanged() {
+ for (Map<ShapeOwnerBullet *, int>::Element *E = owners.front(); E; E = E->next()) {
+ static_cast<ShapeOwnerBullet *>(E->key())->on_shape_changed(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);
+ ERR_FAIL_COND(!E);
+ 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;
+}
+
+btEmptyShape *ShapeBullet::create_shape_empty() {
+ return bulletnew(btEmptyShape);
+}
+
+btStaticPlaneShape *ShapeBullet::create_shape_plane(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));
+}
+
+btCapsuleShapeZ *ShapeBullet::create_shape_capsule(btScalar radius, btScalar height) {
+ return bulletnew(btCapsuleShapeZ(radius, height));
+}
+
+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 NULL;
+ }
+}
+
+btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) {
+ const btScalar ignoredHeightScale(1);
+ const btScalar fieldHeight(500); // Meters
+ const int YAxis = 1; // 0=X, 1=Y, 2=Z
+ const bool flipQuadEdges = false;
+ const void *heightsPtr = p_heights.read().ptr();
+
+ return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, -fieldHeight, fieldHeight, YAxis, PHY_FLOAT, flipQuadEdges));
+}
+
+btRayShape *ShapeBullet::create_shape_ray(real_t p_length) {
+ return bulletnew(btRayShape(p_length));
+}
+
+/* PLANE */
+
+PlaneShapeBullet::PlaneShapeBullet()
+ : ShapeBullet() {}
+
+void PlaneShapeBullet::set_data(const Variant &p_data) {
+ setup(p_data);
+}
+
+Variant PlaneShapeBullet::get_data() const {
+ return plane;
+}
+
+PhysicsServer::ShapeType PlaneShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_PLANE;
+}
+
+void PlaneShapeBullet::setup(const Plane &p_plane) {
+ plane = p_plane;
+ notifyShapeChanged();
+}
+
+btCollisionShape *PlaneShapeBullet::create_bt_shape() {
+ btVector3 btPlaneNormal;
+ G_TO_B(plane.normal, btPlaneNormal);
+ return prepare(PlaneShapeBullet::create_shape_plane(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;
+}
+
+PhysicsServer::ShapeType SphereShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_SPHERE;
+}
+
+void SphereShapeBullet::setup(real_t p_radius) {
+ radius = p_radius;
+ notifyShapeChanged();
+}
+
+btCollisionShape *SphereShapeBullet::create_bt_shape() {
+ return prepare(ShapeBullet::create_shape_sphere(radius));
+}
+
+/* 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;
+}
+
+PhysicsServer::ShapeType BoxShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_BOX;
+}
+
+void BoxShapeBullet::setup(const Vector3 &p_half_extents) {
+ G_TO_B(p_half_extents, half_extents);
+ notifyShapeChanged();
+}
+
+btCollisionShape *BoxShapeBullet::create_bt_shape() {
+ return prepare(ShapeBullet::create_shape_box(half_extents));
+}
+
+/* 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;
+}
+
+PhysicsServer::ShapeType CapsuleShapeBullet::get_type() const {
+ return PhysicsServer::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() {
+ return prepare(ShapeBullet::create_shape_capsule(radius, height));
+}
+
+/* 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[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;
+}
+
+PhysicsServer::ShapeType ConvexPolygonShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_CONVEX_POLYGON;
+}
+
+void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
+ // Make a copy of verticies
+ 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() {
+ return prepare(ShapeBullet::create_shape_convex(vertices));
+}
+
+/* Concave polygon */
+
+ConcavePolygonShapeBullet::ConcavePolygonShapeBullet()
+ : ShapeBullet(), meshShape(NULL) {}
+
+ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
+ if (meshShape) {
+ delete meshShape->getMeshInterface();
+ delete meshShape;
+ }
+ faces = PoolVector<Vector3>();
+}
+
+void ConcavePolygonShapeBullet::set_data(const Variant &p_data) {
+ setup(p_data);
+}
+
+Variant ConcavePolygonShapeBullet::get_data() const {
+ return faces;
+}
+
+PhysicsServer::ShapeType ConcavePolygonShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_CONCAVE_POLYGON;
+}
+
+void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
+ faces = p_faces;
+ if (meshShape) {
+ /// Clear previous created shape
+ delete meshShape->getMeshInterface();
+ bulletdelete(meshShape);
+ }
+ int src_face_count = faces.size();
+ if (0 < src_face_count) {
+
+ btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh);
+
+ // It counts the faces and assert the array contains the correct number of vertices.
+ ERR_FAIL_COND(src_face_count % 3);
+ src_face_count /= 3;
+ PoolVector<Vector3>::Read r = p_faces.read();
+ const Vector3 *facesr = r.ptr();
+
+ btVector3 supVec_0;
+ btVector3 supVec_1;
+ btVector3 supVec_2;
+ for (int i = 0; i < src_face_count; ++i) {
+ G_TO_B(facesr[i * 3], supVec_0);
+ G_TO_B(facesr[i * 3 + 1], supVec_1);
+ G_TO_B(facesr[i * 3 + 2], supVec_2);
+
+ shapeInterface->addTriangle(supVec_0, supVec_1, supVec_2);
+ }
+
+ const bool useQuantizedAabbCompression = true;
+
+ meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
+ } else {
+ meshShape = NULL;
+ ERR_PRINT("The faces count are 0, the mesh shape cannot be created");
+ }
+ notifyShapeChanged();
+}
+
+btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape() {
+ 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();
+ }
+ return prepare(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("cell_size"));
+ ERR_FAIL_COND(!d.has("heights"));
+
+ int l_width = d["width"];
+ int l_depth = d["depth"];
+ real_t l_cell_size = d["cell_size"];
+ PoolVector<real_t> l_heights = d["heights"];
+
+ ERR_FAIL_COND(l_width <= 0);
+ ERR_FAIL_COND(l_depth <= 0);
+ ERR_FAIL_COND(l_cell_size <= CMP_EPSILON);
+ ERR_FAIL_COND(l_heights.size() != (width * depth));
+ setup(heights, width, depth, cell_size);
+}
+
+Variant HeightMapShapeBullet::get_data() const {
+ ERR_FAIL_V(Variant());
+}
+
+PhysicsServer::ShapeType HeightMapShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_HEIGHTMAP;
+}
+
+void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) {
+ { // Copy
+ const int heights_size = p_heights.size();
+ heights.resize(heights_size);
+ PoolVector<real_t>::Read p_heights_r = p_heights.read();
+ PoolVector<real_t>::Write heights_w = heights.write();
+ for (int i = heights_size - 1; 0 <= i; --i) {
+ heights_w[i] = p_heights_r[i];
+ }
+ }
+ width = p_width;
+ depth = p_depth;
+ cell_size = p_cell_size;
+ notifyShapeChanged();
+}
+
+btCollisionShape *HeightMapShapeBullet::create_bt_shape() {
+ return prepare(ShapeBullet::create_shape_height_field(heights, width, depth, cell_size));
+}
+
+/* Ray shape */
+RayShapeBullet::RayShapeBullet()
+ : ShapeBullet(), length(1) {}
+
+void RayShapeBullet::set_data(const Variant &p_data) {
+ setup(p_data);
+}
+
+Variant RayShapeBullet::get_data() const {
+ return length;
+}
+
+PhysicsServer::ShapeType RayShapeBullet::get_type() const {
+ return PhysicsServer::SHAPE_RAY;
+}
+
+void RayShapeBullet::setup(real_t p_length) {
+ length = p_length;
+ notifyShapeChanged();
+}
+
+btCollisionShape *RayShapeBullet::create_bt_shape() {
+ return prepare(ShapeBullet::create_shape_ray(length));
+}
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
new file mode 100644
index 0000000000..0a56fa1709
--- /dev/null
+++ b/modules/bullet/shape_bullet.h
@@ -0,0 +1,225 @@
+/*************************************************************************/
+/* shape_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btScalar.h"
+#include "LinearMath/btVector3.h"
+#include "core/variant.h"
+#include "geometry.h"
+#include "rid_bullet.h"
+#include "servers/physics_server.h"
+
+class ShapeBullet;
+class btCollisionShape;
+class ShapeOwnerBullet;
+class btBvhTriangleMeshShape;
+
+class ShapeBullet : public RIDBullet {
+
+ Map<ShapeOwnerBullet *, int> owners;
+
+protected:
+ /// return self
+ btCollisionShape *prepare(btCollisionShape *p_btShape) const;
+ void notifyShapeChanged();
+
+public:
+ ShapeBullet();
+ virtual ~ShapeBullet();
+
+ virtual btCollisionShape *create_bt_shape() = 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;
+
+ /// Setup the shape
+ virtual void set_data(const Variant &p_data) = 0;
+ virtual Variant get_data() const = 0;
+
+ virtual PhysicsServer::ShapeType get_type() const = 0;
+
+public:
+ static class btEmptyShape *create_shape_empty();
+ static class btStaticPlaneShape *create_shape_plane(const btVector3 &planeNormal, btScalar planeConstant);
+ static class btSphereShape *create_shape_sphere(btScalar radius);
+ static class btBoxShape *create_shape_box(const btVector3 &boxHalfExtents);
+ static class btCapsuleShapeZ *create_shape_capsule(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(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size);
+ static class btRayShape *create_shape_ray(real_t p_length);
+};
+
+class PlaneShapeBullet : public ShapeBullet {
+
+ Plane plane;
+
+public:
+ PlaneShapeBullet();
+
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+ virtual PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(const Plane &p_plane);
+};
+
+class SphereShapeBullet : public ShapeBullet {
+
+ real_t radius;
+
+public:
+ SphereShapeBullet();
+
+ _FORCE_INLINE_ real_t get_radius() { return radius; }
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+ virtual PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+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 PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(const Vector3 &p_half_extents);
+};
+
+class CapsuleShapeBullet : public ShapeBullet {
+
+ real_t height;
+ real_t radius;
+
+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 PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+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 PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(const Vector<Vector3> &p_vertices);
+};
+
+class ConcavePolygonShapeBullet : public ShapeBullet {
+ class btBvhTriangleMeshShape *meshShape;
+
+public:
+ PoolVector<Vector3> faces;
+
+ ConcavePolygonShapeBullet();
+ virtual ~ConcavePolygonShapeBullet();
+
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+ virtual PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(PoolVector<Vector3> p_faces);
+};
+
+class HeightMapShapeBullet : public ShapeBullet {
+
+public:
+ PoolVector<real_t> heights;
+ int width;
+ int depth;
+ real_t cell_size;
+
+ HeightMapShapeBullet();
+
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+ virtual PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size);
+};
+
+class RayShapeBullet : public ShapeBullet {
+
+public:
+ real_t length;
+
+ RayShapeBullet();
+
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+ virtual PhysicsServer::ShapeType get_type() const;
+ virtual btCollisionShape *create_bt_shape();
+
+private:
+ void setup(real_t p_length);
+};
+#endif
diff --git a/modules/bullet/shape_owner_bullet.cpp b/modules/bullet/shape_owner_bullet.cpp
new file mode 100644
index 0000000000..04b2b01675
--- /dev/null
+++ b/modules/bullet/shape_owner_bullet.cpp
@@ -0,0 +1,32 @@
+/*************************************************************************/
+/* shape_owner_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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_owner_bullet.h"
diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h
new file mode 100644
index 0000000000..d2f3d321c7
--- /dev/null
+++ b/modules/bullet/shape_owner_bullet.h
@@ -0,0 +1,52 @@
+/*************************************************************************/
+/* shape_owner_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 clas that want to use Shapes must inherit this class
+/// E.G. BodyShape is a child of this
+class ShapeOwnerBullet {
+public:
+ /// This is used to set new shape or replace existing
+ //virtual void _internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) = 0;
+ virtual void on_shape_changed(const ShapeBullet *const p_shape) = 0;
+ virtual void on_shapes_changed() = 0;
+ virtual void remove_shape(class ShapeBullet *p_shape) = 0;
+ virtual ~ShapeOwnerBullet() {}
+};
+#endif
diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp
new file mode 100644
index 0000000000..2da65677f5
--- /dev/null
+++ b/modules/bullet/slider_joint_bullet.cpp
@@ -0,0 +1,385 @@
+/*************************************************************************/
+/* slider_joint_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "rigid_body_bullet.h"
+
+SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB)
+ : JointBullet() {
+ btTransform btFrameA;
+ G_TO_B(frameInA, btFrameA);
+ if (rbB) {
+ btTransform btFrameB;
+ G_TO_B(frameInB, 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 Transform SliderJointBullet::getCalculatedTransformA() const {
+ btTransform btTransform = sliderConstraint->getCalculatedTransformA();
+ Transform gTrans;
+ B_TO_G(btTransform, gTrans);
+ return gTrans;
+}
+
+const Transform SliderJointBullet::getCalculatedTransformB() const {
+ btTransform btTransform = sliderConstraint->getCalculatedTransformB();
+ Transform gTrans;
+ B_TO_G(btTransform, gTrans);
+ return gTrans;
+}
+
+const Transform SliderJointBullet::getFrameOffsetA() const {
+ btTransform btTransform = sliderConstraint->getFrameOffsetA();
+ Transform gTrans;
+ B_TO_G(btTransform, gTrans);
+ return gTrans;
+}
+
+const Transform SliderJointBullet::getFrameOffsetB() const {
+ btTransform btTransform = sliderConstraint->getFrameOffsetB();
+ Transform gTrans;
+ B_TO_G(btTransform, gTrans);
+ return gTrans;
+}
+
+Transform SliderJointBullet::getFrameOffsetA() {
+ btTransform btTransform = sliderConstraint->getFrameOffsetA();
+ Transform gTrans;
+ B_TO_G(btTransform, gTrans);
+ return gTrans;
+}
+
+Transform SliderJointBullet::getFrameOffsetB() {
+ btTransform btTransform = sliderConstraint->getFrameOffsetB();
+ Transform 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(PhysicsServer::SliderJointParam p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER: setUpperLinLimit(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER: setLowerLinLimit(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: setSoftnessLimLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: setRestitutionLimLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: setDampingLimLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: setSoftnessDirLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: setRestitutionDirLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING: setDampingDirLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: setDampingOrthoLin(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: setUpperAngLimit(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: setLowerAngLimit(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: setSoftnessLimAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: setRestitutionLimAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: setDampingLimAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: setSoftnessDirAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: setRestitutionDirAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: setDampingDirAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoAng(p_value); break;
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: setDampingOrthoAng(p_value); break;
+ }
+}
+
+real_t SliderJointBullet::get_param(PhysicsServer::SliderJointParam p_param) const {
+ switch (p_param) {
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return getUpperLinLimit();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return getLowerLinLimit();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return getSoftnessLimLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return getRestitutionLimLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return getDampingLimLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return getSoftnessDirLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return getRestitutionDirLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return getDampingDirLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoLin();
+ case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return getDampingOrthoLin();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return getUpperAngLimit();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return getLowerAngLimit();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return getSoftnessLimAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return getRestitutionLimAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return getDampingLimAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return getSoftnessDirAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return getRestitutionDirAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return getDampingDirAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoAng();
+ case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoAng();
+ case PhysicsServer::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
new file mode 100644
index 0000000000..d50c376ea6
--- /dev/null
+++ b/modules/bullet/slider_joint_bullet.h
@@ -0,0 +1,118 @@
+/*************************************************************************/
+/* slider_joint_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 Transform &frameInA, const Transform &frameInB);
+
+ virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_SLIDER; }
+
+ const RigidBodyBullet *getRigidBodyA() const;
+ const RigidBodyBullet *getRigidBodyB() const;
+ const Transform getCalculatedTransformA() const;
+ const Transform getCalculatedTransformB() const;
+ const Transform getFrameOffsetA() const;
+ const Transform getFrameOffsetB() const;
+ Transform getFrameOffsetA();
+ Transform 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(PhysicsServer::SliderJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer::SliderJointParam p_param) const;
+};
+#endif
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
new file mode 100644
index 0000000000..64ef7bfad2
--- /dev/null
+++ b/modules/bullet/soft_body_bullet.cpp
@@ -0,0 +1,303 @@
+/*************************************************************************/
+/* soft_body_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "scene/3d/immediate_geometry.h"
+
+SoftBodyBullet::SoftBodyBullet()
+ : CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY), mass(1), simulation_precision(5), stiffness(0.5f), pressure_coefficient(50), damping_coefficient(0.005), drag_coefficient(0.005), bt_soft_body(NULL), soft_shape_type(SOFT_SHAPETYPE_NONE), isScratched(false), soft_body_shape_data(NULL) {
+
+ test_geometry = memnew(ImmediateGeometry);
+
+ red_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ red_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ red_mat->set_line_width(20.0);
+ red_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ red_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ red_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ red_mat->set_albedo(Color(1, 0, 0, 1));
+ test_geometry->set_material_override(red_mat);
+
+ test_is_in_scene = false;
+}
+
+SoftBodyBullet::~SoftBodyBullet() {
+ bulletdelete(soft_body_shape_data);
+}
+
+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;
+
+ // Remove this object from the physics world
+ space->remove_soft_body(this);
+ }
+
+ space = p_space;
+
+ if (space) {
+ space->add_soft_body(this);
+ }
+
+ reload_soft_body();
+}
+
+void SoftBodyBullet::dispatch_callbacks() {
+ if (!bt_soft_body) {
+ return;
+ }
+
+ if (!test_is_in_scene) {
+ test_is_in_scene = true;
+ SceneTree::get_singleton()->get_current_scene()->add_child(test_geometry);
+ }
+
+ test_geometry->clear();
+ test_geometry->begin(Mesh::PRIMITIVE_LINES, NULL);
+ bool first = true;
+ Vector3 pos;
+ for (int i = 0; i < bt_soft_body->m_nodes.size(); ++i) {
+ const btSoftBody::Node &n = bt_soft_body->m_nodes[i];
+ B_TO_G(n.m_x, pos);
+ test_geometry->add_vertex(pos);
+ if (!first) {
+ test_geometry->add_vertex(pos);
+ } else {
+ first = false;
+ }
+ }
+ test_geometry->end();
+}
+
+void SoftBodyBullet::on_collision_filters_change() {
+}
+
+void SoftBodyBullet::on_collision_checker_start() {
+}
+
+void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {
+}
+
+void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {
+}
+
+void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVector<Vector3> p_vertices, int p_triangles_num) {
+
+ TrimeshSoftShapeData *shape_data = bulletnew(TrimeshSoftShapeData);
+ shape_data->m_triangles_indices = p_indices;
+ shape_data->m_vertices = p_vertices;
+ shape_data->m_triangles_num = p_triangles_num;
+
+ set_body_shape_data(shape_data, SOFT_SHAPE_TYPE_TRIMESH);
+ reload_soft_body();
+}
+
+void SoftBodyBullet::set_body_shape_data(SoftShapeData *p_soft_shape_data, SoftShapeType p_type) {
+ bulletdelete(soft_body_shape_data);
+ soft_body_shape_data = p_soft_shape_data;
+ soft_shape_type = p_type;
+}
+
+void SoftBodyBullet::set_transform(const Transform &p_transform) {
+ transform = p_transform;
+ if (bt_soft_body) {
+ // TODO the softbody set new transform considering the current transform as center of world
+ // like if it's local transform, so I must fix this by setting nwe transform considering the old
+ btTransform bt_trans;
+ G_TO_B(transform, bt_trans);
+ //bt_soft_body->transform(bt_trans);
+ }
+}
+
+const Transform &SoftBodyBullet::get_transform() const {
+ return transform;
+}
+
+void SoftBodyBullet::get_first_node_origin(btVector3 &p_out_origin) const {
+ if (bt_soft_body && bt_soft_body->m_nodes.size()) {
+ p_out_origin = bt_soft_body->m_nodes[0].m_x;
+ } else {
+ p_out_origin.setZero();
+ }
+}
+
+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_mass(real_t p_val) {
+ if (0 >= p_val) {
+ p_val = 1;
+ }
+ mass = p_val;
+ if (bt_soft_body) {
+ bt_soft_body->setTotalMass(mass);
+ }
+}
+
+void SoftBodyBullet::set_stiffness(real_t p_val) {
+ stiffness = p_val;
+ if (bt_soft_body) {
+ mat0->m_kAST = stiffness;
+ mat0->m_kLST = stiffness;
+ mat0->m_kVST = 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;
+ }
+}
+
+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;
+ }
+}
+
+void SoftBodyBullet::reload_soft_body() {
+
+ destroy_soft_body();
+ create_soft_body();
+
+ if (bt_soft_body) {
+
+ // TODO the softbody set new transform considering the current transform as center of world
+ // like if it's local transform, so I must fix this by setting nwe transform considering the old
+ btTransform bt_trans;
+ G_TO_B(transform, bt_trans);
+ bt_soft_body->transform(bt_trans);
+
+ bt_soft_body->generateBendingConstraints(2, mat0);
+ mat0->m_kAST = stiffness;
+ mat0->m_kLST = stiffness;
+ mat0->m_kVST = stiffness;
+
+ bt_soft_body->m_cfg.piterations = 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(mass);
+ }
+ if (space) {
+ // TODO remove this please
+ space->add_soft_body(this);
+ }
+}
+
+void SoftBodyBullet::create_soft_body() {
+ if (!space || !soft_body_shape_data) {
+ return;
+ }
+ ERR_FAIL_COND(!space->is_using_soft_world());
+ switch (soft_shape_type) {
+ case SOFT_SHAPE_TYPE_TRIMESH: {
+ TrimeshSoftShapeData *trimesh_data = static_cast<TrimeshSoftShapeData *>(soft_body_shape_data);
+
+ Vector<int> indices;
+ Vector<btScalar> vertices;
+
+ int i;
+ const int indices_size = trimesh_data->m_triangles_indices.size();
+ const int vertices_size = trimesh_data->m_vertices.size();
+ indices.resize(indices_size);
+ vertices.resize(vertices_size * 3);
+
+ PoolVector<int>::Read i_r = trimesh_data->m_triangles_indices.read();
+ for (i = 0; i < indices_size; ++i) {
+ indices[i] = i_r[i];
+ }
+ i_r = PoolVector<int>::Read();
+
+ PoolVector<Vector3>::Read f_r = trimesh_data->m_vertices.read();
+ for (int j = i = 0; i < vertices_size; ++i, j += 3) {
+ vertices[j + 0] = f_r[i][0];
+ vertices[j + 1] = f_r[i][1];
+ vertices[j + 2] = f_r[i][2];
+ }
+ f_r = PoolVector<Vector3>::Read();
+
+ bt_soft_body = btSoftBodyHelpers::CreateFromTriMesh(*space->get_soft_body_world_info(), vertices.ptr(), indices.ptr(), trimesh_data->m_triangles_num);
+ } break;
+ default:
+ ERR_PRINT("Shape type not supported");
+ return;
+ }
+
+ setupBulletCollisionObject(bt_soft_body);
+ bt_soft_body->getCollisionShape()->setMargin(0.001f);
+ bt_soft_body->setCollisionFlags(bt_soft_body->getCollisionFlags() & (~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT)));
+ mat0 = bt_soft_body->appendMaterial();
+}
+
+void SoftBodyBullet::destroy_soft_body() {
+ if (space) {
+ /// This step is required to assert that the body is not into the world during deletion
+ /// This step is required since to change the body shape the body must be re-created.
+ /// Here is handled the case when the body is assigned into a world and the body
+ /// shape is changed.
+ space->remove_soft_body(this);
+ }
+ destroyBulletCollisionObject();
+ bt_soft_body = NULL;
+}
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
new file mode 100644
index 0000000000..9ee7cd76d3
--- /dev/null
+++ b/modules/bullet/soft_body_bullet.h
@@ -0,0 +1,136 @@
+/*************************************************************************/
+/* soft_body_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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
+
+#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"
+
+#ifdef x11_None
+/// This is required to re add the macro None defined by x11 compiler
+#undef x11_None
+#define None 0L
+#endif
+
+#include "scene/resources/material.h" // TODO remove thsi please
+
+struct SoftShapeData {};
+struct TrimeshSoftShapeData : public SoftShapeData {
+ PoolVector<int> m_triangles_indices;
+ PoolVector<Vector3> m_vertices;
+ int m_triangles_num;
+};
+
+class SoftBodyBullet : public CollisionObjectBullet {
+public:
+ enum SoftShapeType {
+ SOFT_SHAPETYPE_NONE = 0,
+ SOFT_SHAPE_TYPE_TRIMESH
+ };
+
+private:
+ btSoftBody *bt_soft_body;
+ btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
+ SoftShapeType soft_shape_type;
+ bool isScratched;
+
+ SoftShapeData *soft_body_shape_data;
+
+ Transform transform;
+ int simulation_precision;
+ real_t mass;
+ real_t stiffness; // [0,1]
+ real_t pressure_coefficient; // [-inf,+inf]
+ real_t damping_coefficient; // [0,1]
+ real_t drag_coefficient; // [0,1]
+
+ class ImmediateGeometry *test_geometry; // TODO remove this please
+ Ref<SpatialMaterial> red_mat; // TODO remove this please
+ bool test_is_in_scene; // TODO remove this please
+
+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_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 set_trimesh_body_shape(PoolVector<int> p_indices, PoolVector<Vector3> p_vertices, int p_triangles_num);
+ void set_body_shape_data(SoftShapeData *p_soft_shape_data, SoftShapeType p_type);
+
+ void set_transform(const Transform &p_transform);
+ /// This function doesn't return the exact COM transform.
+ /// It returns the origin only of first node (vertice) of current soft body
+ /// ---
+ /// The soft body doesn't have a fixed center of mass, but is a group of nodes (vertices)
+ /// that each has its own position in the world.
+ /// For this reason return the correct COM is not so simple and must be calculate
+ /// Check this to improve this function http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=8803
+ const Transform &get_transform() const;
+ void get_first_node_origin(btVector3 &p_out_origin) const;
+
+ void set_activation_state(bool p_active);
+
+ void set_mass(real_t p_val);
+ _FORCE_INLINE_ real_t get_mass() const { return mass; }
+ void set_stiffness(real_t p_val);
+ _FORCE_INLINE_ real_t get_stiffness() const { return 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:
+ void reload_soft_body();
+ void create_soft_body();
+ void destroy_soft_body();
+};
+
+#endif // SOFT_BODY_BULLET_H
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
new file mode 100644
index 0000000000..9df01aee3e
--- /dev/null
+++ b/modules/bullet/space_bullet.cpp
@@ -0,0 +1,1101 @@
+/*************************************************************************/
+/* space_bullet.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "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 "bullet_physics_server.h"
+#include "bullet_types_converter.h"
+#include "bullet_utilities.h"
+#include "constraint_bullet.h"
+#include "godot_collision_configuration.h"
+#include "godot_collision_dispatcher.h"
+#include "rigid_body_bullet.h"
+#include "servers/physics_server.h"
+#include "soft_body_bullet.h"
+#include "ustring.h"
+#include <assert.h>
+
+BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space)
+ : PhysicsDirectSpaceState(), 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_layer, uint32_t p_object_type_mask) {
+
+ if (p_result_max <= 0)
+ return 0;
+
+ btVector3 bt_point;
+ G_TO_B(p_point, bt_point);
+
+ btSphereShape sphere_point(0.f);
+ 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);
+ btResult.m_collisionFilterGroup = p_collision_layer;
+ btResult.m_collisionFilterMask = p_object_type_mask;
+ space->dynamicsWorld->contactTest(&collision_object_point, btResult);
+
+ // The results is 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_layer, uint32_t p_object_type_mask, 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);
+ btResult.m_collisionFilterGroup = p_collision_layer;
+ btResult.m_collisionFilterMask = p_object_type_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 = 0;
+ r_result.rid = gObj->get_self();
+ r_result.collider_id = gObj->get_instance_id();
+ r_result.collider = 0 == r_result.collider_id ? NULL : ObjectDB::get_instance(r_result.collider_id);
+ } else {
+ WARN_PRINTS("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 Transform &p_xform, float p_margin, ShapeResult *p_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
+ if (p_result_max <= 0)
+ return 0;
+
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+
+ btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape());
+ if (!btConvex) {
+ bulletdelete(btConvex);
+ ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
+ return 0;
+ }
+
+ btVector3 scale_with_margin;
+ G_TO_B(p_xform.basis.get_scale(), scale_with_margin);
+ btConvex->setLocalScaling(scale_with_margin);
+
+ btTransform bt_xform;
+ G_TO_B(p_xform, bt_xform);
+
+ btCollisionObject collision_object;
+ collision_object.setCollisionShape(btConvex);
+ collision_object.setWorldTransform(bt_xform);
+
+ GodotAllContactResultCallback btQuery(&collision_object, p_results, p_result_max, &p_exclude);
+ btQuery.m_collisionFilterGroup = p_collision_layer;
+ btQuery.m_collisionFilterMask = p_object_type_mask;
+ btQuery.m_closestDistanceThreshold = p_margin;
+ space->dynamicsWorld->contactTest(&collision_object, btQuery);
+
+ bulletdelete(btConvex);
+
+ return btQuery.m_count;
+}
+
+bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, ShapeRestInfo *r_info) {
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+
+ btConvexShape *bt_convex_shape = dynamic_cast<btConvexShape *>(shape->create_bt_shape());
+ if (!bt_convex_shape) {
+ bulletdelete(bt_convex_shape);
+ ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
+ return 0;
+ }
+
+ btVector3 bt_motion;
+ G_TO_B(p_motion, bt_motion);
+
+ btVector3 scale_with_margin;
+ G_TO_B(p_xform.basis.get_scale() + Vector3(p_margin, p_margin, p_margin), scale_with_margin);
+ bt_convex_shape->setLocalScaling(scale_with_margin);
+
+ btTransform bt_xform_from;
+ G_TO_B(p_xform, bt_xform_from);
+
+ btTransform bt_xform_to(bt_xform_from);
+ bt_xform_to.getOrigin() += bt_motion;
+
+ GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude);
+ btResult.m_collisionFilterGroup = p_collision_layer;
+ btResult.m_collisionFilterMask = p_object_type_mask;
+
+ space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002);
+
+ if (btResult.hasHit()) {
+ 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());
+ p_closest_safe = p_closest_unsafe = btResult.m_closestHitFraction;
+ 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_shapePart;
+ }
+
+ bulletdelete(bt_convex_shape);
+ return btResult.hasHit();
+}
+
+/// Returns the list of contacts pairs in this order: Local contact, other body contact
+bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
+ if (p_result_max <= 0)
+ return 0;
+
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+
+ btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape());
+ if (!btConvex) {
+ bulletdelete(btConvex);
+ ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
+ return 0;
+ }
+
+ btVector3 scale_with_margin;
+ G_TO_B(p_shape_xform.basis.get_scale(), scale_with_margin);
+ btConvex->setLocalScaling(scale_with_margin);
+
+ btTransform bt_xform;
+ G_TO_B(p_shape_xform, 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);
+ btQuery.m_collisionFilterGroup = p_collision_layer;
+ btQuery.m_collisionFilterMask = p_object_type_mask;
+ btQuery.m_closestDistanceThreshold = p_margin;
+ 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 Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
+
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+
+ btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape());
+ if (!btConvex) {
+ bulletdelete(btConvex);
+ ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
+ return 0;
+ }
+
+ btVector3 scale_with_margin;
+ G_TO_B(p_shape_xform.basis.get_scale() + Vector3(p_margin, p_margin, p_margin), scale_with_margin);
+ btConvex->setLocalScaling(scale_with_margin);
+
+ btTransform bt_xform;
+ G_TO_B(p_shape_xform, bt_xform);
+
+ btCollisionObject collision_object;
+ collision_object.setCollisionShape(btConvex);
+ collision_object.setWorldTransform(bt_xform);
+
+ GodotRestInfoContactResultCallback btQuery(&collision_object, r_info, &p_exclude);
+ btQuery.m_collisionFilterGroup = p_collision_layer;
+ btQuery.m_collisionFilterMask = p_object_type_mask;
+ btQuery.m_closestDistanceThreshold = p_margin;
+ 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_collisin_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;
+
+ btCompoundShape *compound = rigid_object->get_compound_shape();
+ for (int i = compound->getNumChildShapes() - 1; 0 <= i; --i) {
+ shape = compound->getChildShape(i);
+ if (shape->isConvex()) {
+ child_transform = compound->getChildTransform(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, 0);
+
+ 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(bool p_create_soft_world)
+ : broadphase(NULL),
+ dispatcher(NULL),
+ solver(NULL),
+ collisionConfiguration(NULL),
+ dynamicsWorld(NULL),
+ soft_body_world_info(NULL),
+ ghostPairCallback(NULL),
+ godotFilterCallback(NULL),
+ gravityDirection(0, -1, 0),
+ gravityMagnitude(10),
+ contactDebugCount(0) {
+
+ create_empty_world(p_create_soft_world);
+ 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) {
+ dynamicsWorld->stepSimulation(p_delta_time, 0, 0);
+}
+
+void SpaceBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value) {
+ assert(dynamicsWorld);
+
+ switch (p_param) {
+ case PhysicsServer::AREA_PARAM_GRAVITY:
+ gravityMagnitude = p_value;
+ update_gravity();
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ gravityDirection = p_value;
+ update_gravity();
+ break;
+ case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ break; // No damp
+ case PhysicsServer::AREA_PARAM_PRIORITY:
+ // Priority is always 0, the lower
+ break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ break;
+ default:
+ WARN_PRINTS("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
+ break;
+ }
+}
+
+Variant SpaceBullet::get_param(PhysicsServer::AreaParameter p_param) {
+ switch (p_param) {
+ case PhysicsServer::AREA_PARAM_GRAVITY:
+ return gravityMagnitude;
+ case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ return gravityDirection;
+ case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ return 0; // No damp
+ case PhysicsServer::AREA_PARAM_PRIORITY:
+ return 0; // Priority is always 0, the lower
+ case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ return false;
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ return 0;
+ case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ return 0;
+ default:
+ WARN_PRINTS("This get parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
+ return Variant();
+ }
+}
+
+void SpaceBullet::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) {
+ switch (p_param) {
+ case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ default:
+ WARN_PRINTS("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
+ break;
+ }
+}
+
+real_t SpaceBullet::get_param(PhysicsServer::SpaceParameter p_param) {
+ switch (p_param) {
+ case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ default:
+ WARN_PRINTS("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) {
+ // This is necessary to change collision filter
+ dynamicsWorld->removeCollisionObject(p_area->get_bt_ghost());
+ dynamicsWorld->addCollisionObject(p_area->get_bt_ghost(), p_area->get_collision_layer(), p_area->get_collision_mask());
+}
+
+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());
+ }
+}
+
+void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) {
+ if (p_body->is_static()) {
+ dynamicsWorld->removeCollisionObject(p_body->get_bt_rigid_body());
+ } else {
+ dynamicsWorld->removeRigidBody(p_body->get_bt_rigid_body());
+ }
+}
+
+void SpaceBullet::reload_collision_filters(RigidBodyBullet *p_body) {
+ // This is necessary to change collision filter
+ remove_rigid_body(p_body);
+ add_rigid_body(p_body);
+}
+
+void SpaceBullet::add_soft_body(SoftBodyBullet *p_body) {
+ if (is_using_soft_world()) {
+ if (p_body->get_bt_soft_body()) {
+ 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());
+ }
+ }
+}
+
+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(NULL);
+ }
+}
+
+void onBulletPreTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep) {
+ static_cast<SpaceBullet *>(p_dynamicsWorld->getWorldUserInfo())->flush_queries();
+}
+
+void onBulletTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep) {
+
+ // Notify all Collision objects the collision checker is started
+ const btCollisionObjectArray &colObjArray = p_dynamicsWorld->getCollisionObjectArray();
+ for (int i = colObjArray.size() - 1; 0 <= i; --i) {
+ CollisionObjectBullet *colObj = static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer());
+ assert(NULL != colObj);
+ colObj->on_collision_checker_start();
+ }
+
+ SpaceBullet *sb = static_cast<SpaceBullet *>(p_dynamicsWorld->getWorldUserInfo());
+ sb->check_ghost_overlaps();
+ sb->check_body_collision();
+}
+
+BulletPhysicsDirectSpaceState *SpaceBullet::get_direct_state() {
+ return direct_access;
+}
+
+btScalar calculateGodotCombinedRestitution(const btCollisionObject *body0, const btCollisionObject *body1) {
+ return MAX(body0->getRestitution(), body1->getRestitution());
+}
+
+void SpaceBullet::create_empty_world(bool p_create_soft_world) {
+
+ gjk_epa_pen_solver = bulletnew(btGjkEpaPenetrationDepthSolver);
+ gjk_simplex_solver = bulletnew(btVoronoiSimplexSolver);
+ gjk_simplex_solver->setEqualVertexThreshold(0.f);
+
+ void *world_mem;
+ if (p_create_soft_world) {
+ world_mem = malloc(sizeof(btSoftRigidDynamicsWorld));
+ } else {
+ world_mem = malloc(sizeof(btDiscreteDynamicsWorld));
+ }
+
+ if (p_create_soft_world) {
+ collisionConfiguration = bulletnew(btSoftBodyRigidBodyCollisionConfiguration);
+ } 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;
+
+ dynamicsWorld->setWorldUserInfo(this);
+
+ dynamicsWorld->setInternalTickCallback(onBulletPreTickCallback, this, true);
+ 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(NULL);
+ dynamicsWorld->getPairCache()->setOverlapFilterCallback(NULL);
+
+ bulletdelete(ghostPairCallback);
+ bulletdelete(godotFilterCallback);
+
+ // Deallocate world
+ dynamicsWorld->~btDiscreteDynamicsWorld();
+ free(dynamicsWorld);
+ dynamicsWorld = NULL;
+
+ 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() {
+
+ /// Algorith support variables
+ btConvexShape *other_body_shape;
+ btConvexShape *area_shape;
+ btGjkPairDetector::ClosestPointInput gjk_input;
+ AreaBullet *area;
+ RigidCollisionObjectBullet *otherObject;
+ int x(-1), i(-1), y(-1), z(-1), indexOverlap(-1);
+
+ /// For each areas
+ for (x = areas.size() - 1; 0 <= x; --x) {
+ area = areas[x];
+
+ if (!area->is_monitoring())
+ continue;
+
+ /// 1. Reset all states
+ for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) {
+ AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects[i];
+ // This check prevent the overwrite of ENTER state
+ // if this function is called more times before dispatchCallbacks
+ if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) {
+ otherObj.state = AreaBullet::OVERLAP_STATE_DIRTY;
+ }
+ }
+
+ /// 2. Check all overlapping objects using GJK
+
+ const btAlignedObjectArray<btCollisionObject *> ghostOverlaps = area->get_bt_ghost()->getOverlappingPairs();
+
+ // For each overlapping
+ for (i = ghostOverlaps.size() - 1; 0 <= i; --i) {
+
+ if (!(ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_RIGID_BODY || ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA))
+ continue;
+
+ otherObject = static_cast<RigidCollisionObjectBullet *>(ghostOverlaps[i]->getUserPointer());
+
+ bool hasOverlap = false;
+
+ // For each area shape
+ for (y = area->get_compound_shape()->getNumChildShapes() - 1; 0 <= y; --y) {
+ if (!area->get_compound_shape()->getChildShape(y)->isConvex())
+ continue;
+
+ gjk_input.m_transformA = area->get_transform__bullet() * area->get_compound_shape()->getChildTransform(y);
+ area_shape = static_cast<btConvexShape *>(area->get_compound_shape()->getChildShape(y));
+
+ // For each other object shape
+ for (z = otherObject->get_compound_shape()->getNumChildShapes() - 1; 0 <= z; --z) {
+
+ if (!otherObject->get_compound_shape()->getChildShape(z)->isConvex())
+ continue;
+
+ other_body_shape = static_cast<btConvexShape *>(otherObject->get_compound_shape()->getChildShape(z));
+ gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_compound_shape()->getChildTransform(z);
+
+ btPointCollector result;
+ btGjkPairDetector gjk_pair_detector(area_shape, other_body_shape, gjk_simplex_solver, gjk_epa_pen_solver);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+
+ if (0 >= result.m_distance) {
+ hasOverlap = true;
+ goto collision_found;
+ }
+ } // ~For each other object shape
+ } // ~For each area shape
+
+ collision_found:
+ if (!hasOverlap)
+ continue;
+
+ indexOverlap = area->find_overlapping_object(otherObject);
+ if (-1 == indexOverlap) {
+ // Not found
+ area->add_overlap(otherObject);
+ } else {
+ // Found
+ area->put_overlap_as_inside(indexOverlap);
+ }
+ }
+
+ /// 3. Remove not overlapping
+ for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) {
+ // If the overlap has DIRTY state it means that it's no more overlapping
+ if (area->overlappingObjects[i].state == AreaBullet::OVERLAP_STATE_DIRTY) {
+ area->put_overlap_as_exit(i);
+ }
+ }
+ }
+}
+
+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();
+#define REPORT_ALL_CONTACTS 0
+#if REPORT_ALL_CONTACTS
+ for (int j = 0; j < numContacts; j++) {
+ btManifoldPoint &pt = contactManifold->getContactPoint(j);
+#else
+ // Since I don't need report all contacts for these objects, I'll report only the first
+ if (numContacts) {
+ btManifoldPoint &pt = contactManifold->getContactPoint(0);
+#endif
+ Vector3 collisionWorldPosition;
+ Vector3 collisionLocalPosition;
+ Vector3 normalOnB;
+ B_TO_G(pt.m_normalWorldOnB, normalOnB);
+
+ 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, pt.m_index1, pt.m_index0);
+ }
+ 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, pt.m_index0, pt.m_index1);
+ }
+
+#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);
+ 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 PERFORM_INITIAL_UNSTACK 1
+
+#if debug_test_motion
+
+#include "scene/3d/immediate_geometry.h"
+
+static ImmediateGeometry *motionVec(NULL);
+static ImmediateGeometry *normalLine(NULL);
+static Ref<SpatialMaterial> red_mat;
+static Ref<SpatialMaterial> blue_mat;
+#endif
+
+#define IGNORE_AREAS_TRUE true
+bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result) {
+
+#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(ImmediateGeometry);
+ normalLine = memnew(ImmediateGeometry);
+ SceneTree::get_singleton()->get_current_scene()->add_child(motionVec);
+ SceneTree::get_singleton()->get_current_scene()->add_child(normalLine);
+
+ red_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ red_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ red_mat->set_line_width(20.0);
+ red_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ red_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ red_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ red_mat->set_albedo(Color(1, 0, 0, 1));
+ motionVec->set_material_override(red_mat);
+
+ blue_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ blue_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ blue_mat->set_line_width(20.0);
+ blue_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ blue_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ blue_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ blue_mat->set_albedo(Color(0, 0, 1, 1));
+ normalLine->set_material_override(blue_mat);
+ }
+#endif
+
+ ///// Release all generated manifolds
+ //{
+ // if(p_body->get_kinematic_utilities()){
+ // for(int i= p_body->get_kinematic_utilities()->m_generatedManifold.size()-1; 0<=i; --i){
+ // dispatcher->releaseManifold( p_body->get_kinematic_utilities()->m_generatedManifold[i] );
+ // }
+ // p_body->get_kinematic_utilities()->m_generatedManifold.clear();
+ // }
+ //}
+
+ btVector3 recover_initial_position(0, 0, 0);
+
+ btTransform body_safe_position;
+ G_TO_B(p_from, body_safe_position);
+
+ { /// Phase one - multi shapes depenetration using margin
+#if PERFORM_INITIAL_UNSTACK
+ if (recover_from_penetration(p_body, body_safe_position, recover_initial_position)) {
+
+ // Add recover position to "From" and "To" transforms
+ body_safe_position.getOrigin() += recover_initial_position;
+ }
+#endif
+ }
+
+ btVector3 recovered_motion;
+ G_TO_B(p_motion, recovered_motion);
+ const int shape_count(p_body->get_shape_count());
+
+ { /// phase two - sweep test, from a secure position without margin
+
+#if debug_test_motion
+ Vector3 sup_line;
+ B_TO_G(body_safe_position.getOrigin(), sup_line);
+ motionVec->clear();
+ motionVec->begin(Mesh::PRIMITIVE_LINES, NULL);
+ 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;
+ }
+
+ btConvexShape *convex_shape_test(dynamic_cast<btConvexShape *>(p_body->get_bt_shape(shIndex)));
+ if (!convex_shape_test) {
+ // Skip no convex shape
+ continue;
+ }
+
+ btTransform shape_world_from;
+ G_TO_B(p_body->get_shape_transform(shIndex), shape_world_from);
+
+ // Add local shape transform
+ shape_world_from = body_safe_position * shape_world_from;
+
+ btTransform shape_world_to(shape_world_from);
+ shape_world_to.getOrigin() += recovered_motion;
+
+ GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, IGNORE_AREAS_TRUE);
+ 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, 0.002);
+
+ if (btResult.hasHit()) {
+ /// 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
+ recovered_motion *= btResult.m_closestHitFraction;
+ }
+ }
+ }
+
+ bool hasPenetration = false;
+
+ { /// Phase three - Recover + contact test with margin
+
+ RecoverResult recover_result;
+
+ hasPenetration = recover_from_penetration(p_body, body_safe_position, recovered_motion, &recover_result);
+
+ if (r_result) {
+
+ B_TO_G(recovered_motion + recover_initial_position, r_result->motion);
+
+ if (hasPenetration) {
+ const btRigidBody *btRigid = static_cast<const btRigidBody *>(recover_result.other_collision_object);
+ CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer());
+
+ r_result->remainder = p_motion - r_result->motion; // is the remaining movements
+ B_TO_G(recover_result.pointWorld, r_result->collision_point);
+ B_TO_G(recover_result.pointNormalWorld, r_result->collision_normal);
+ B_TO_G(btRigid->getVelocityInLocalPoint(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 = recover_result.other_compound_shape_index;
+ r_result->collision_local_shape = recover_result.local_shape_most_recovered;
+
+//{ /// Add manifold point to manage collisions
+// btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid);
+// btManifoldPoint manifoldPoint(result_callabck.m_pointWorld, result_callabck.m_pointWorld, result_callabck.m_pointNormalWorld, result_callabck.m_penetration_distance);
+// manifoldPoint.m_index0 = r_result->collision_local_shape;
+// manifoldPoint.m_index1 = r_result->collider_shape;
+// manifold->addManifoldPoint(manifoldPoint);
+// p_body->get_kinematic_utilities()->m_generatedManifold.push_back(manifold);
+//}
+
+#if debug_test_motion
+ Vector3 sup_line2;
+ B_TO_G(recovered_motion, sup_line2);
+ //Vector3 sup_pos;
+ //B_TO_G( pt.getPositionWorldOnB(), sup_pos);
+ normalLine->clear();
+ normalLine->begin(Mesh::PRIMITIVE_LINES, NULL);
+ 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 hasPenetration;
+}
+
+struct RecoverPenetrationBroadPhaseCallback : public btBroadphaseAabbCallback {
+private:
+ const btCollisionObject *self_collision_object;
+ uint32_t collision_layer;
+ uint32_t collision_mask;
+
+public:
+ Vector<btCollisionObject *> result_collision_objects;
+
+public:
+ RecoverPenetrationBroadPhaseCallback(const btCollisionObject *p_self_collision_object, uint32_t p_collision_layer, uint32_t p_collision_mask)
+ : self_collision_object(p_self_collision_object),
+ collision_layer(p_collision_layer),
+ collision_mask(p_collision_mask) {}
+
+ 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 && GodotFilterCallback::test_collision_filters(collision_layer, collision_mask, proxy->m_collisionFilterGroup, proxy->m_collisionFilterMask)) {
+ result_collision_objects.push_back(co);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void reset() {
+ result_collision_objects.empty();
+ }
+};
+
+bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btVector3 &out_recover_position, RecoverResult *recover_result) {
+
+ RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask());
+
+ btTransform body_shape_position;
+ btTransform body_shape_position_recovered;
+
+ // Broad phase support
+ btVector3 minAabb, maxAabb;
+
+ // GJK support
+ btGjkPairDetector::ClosestPointInput gjk_input;
+
+ bool penetration = false;
+
+ // For each shape
+ for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) {
+
+ recover_broad_result.reset();
+
+ const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]);
+ if (!kin_shape.is_active()) {
+ continue;
+ }
+
+ body_shape_position = p_body_position * kin_shape.transform;
+ body_shape_position_recovered = body_shape_position;
+ body_shape_position_recovered.getOrigin() += out_recover_position;
+
+ kin_shape.shape->getAabb(body_shape_position_recovered, minAabb, maxAabb);
+ dynamicsWorld->getBroadphase()->aabbTest(minAabb, maxAabb, recover_broad_result);
+
+ for (int i = recover_broad_result.result_collision_objects.size() - 1; 0 <= i; --i) {
+ btCollisionObject *otherObject = recover_broad_result.result_collision_objects[i];
+ if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object()))
+ continue;
+
+ if (otherObject->getCollisionShape()->isCompound()) { /// Execute GJK test against all shapes
+
+ // Each convex shape
+ btCompoundShape *cs = static_cast<btCompoundShape *>(otherObject->getCollisionShape());
+ for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) {
+
+ if (!cs->getChildShape(x)->isConvex())
+ continue;
+
+ // Initialize GJK input
+ gjk_input.m_transformA = body_shape_position;
+ gjk_input.m_transformA.getOrigin() += out_recover_position;
+ gjk_input.m_transformB = otherObject->getWorldTransform() * cs->getChildTransform(x);
+
+ // Perform GJK test
+ btPointCollector result;
+ btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), gjk_simplex_solver, gjk_epa_pen_solver);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ if (0 > result.m_distance) {
+ // Has penetration
+ out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1);
+ penetration = true;
+
+ if (recover_result) {
+
+ recover_result->hasPenetration = true;
+ recover_result->other_collision_object = otherObject;
+ recover_result->other_compound_shape_index = x;
+ recover_result->penetration_distance = result.m_distance;
+ recover_result->pointNormalWorld = result.m_normalOnBInWorld;
+ recover_result->pointWorld = result.m_pointInWorld;
+ }
+ }
+ }
+
+ } else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape
+
+ // Initialize GJK input
+ gjk_input.m_transformA = body_shape_position;
+ gjk_input.m_transformA.getOrigin() += out_recover_position;
+ gjk_input.m_transformB = otherObject->getWorldTransform();
+
+ // Perform GJK test
+ btPointCollector result;
+ btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), gjk_simplex_solver, gjk_epa_pen_solver);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ if (0 > result.m_distance) {
+ // Has penetration
+ out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1);
+ penetration = true;
+
+ if (recover_result) {
+
+ recover_result->hasPenetration = true;
+ recover_result->other_collision_object = otherObject;
+ recover_result->other_compound_shape_index = 0;
+ recover_result->penetration_distance = result.m_distance;
+ recover_result->pointNormalWorld = result.m_normalOnBInWorld;
+ recover_result->pointWorld = result.m_pointInWorld;
+ }
+ }
+ }
+ }
+ }
+
+ return penetration;
+}
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
new file mode 100644
index 0000000000..d9206f8046
--- /dev/null
+++ b/modules/bullet/space_bullet.h
@@ -0,0 +1,194 @@
+/*************************************************************************/
+/* space_bullet.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btScalar.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "core/variant.h"
+#include "core/vector.h"
+#include "godot_result_callbacks.h"
+#include "rid_bullet.h"
+#include "servers/physics_server.h"
+
+class AreaBullet;
+class btBroadphaseInterface;
+class btCollisionDispatcher;
+class btConstraintSolver;
+class btDefaultCollisionConfiguration;
+class btDynamicsWorld;
+class btDiscreteDynamicsWorld;
+class btEmptyShape;
+class btGhostPairCallback;
+class btSoftRigidDynamicsWorld;
+class btSoftBodyWorldInfo;
+class ConstraintBullet;
+class CollisionObjectBullet;
+class RigidBodyBullet;
+class SpaceBullet;
+class SoftBodyBullet;
+class btGjkEpaPenetrationDepthSolver;
+
+class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState {
+ GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState)
+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_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ 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_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
+ /// Returns the list of contacts pairs in this order: Local contact, other body contact
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const;
+};
+
+class SpaceBullet : public RIDBullet {
+private:
+ friend class AreaBullet;
+ friend void onBulletTickCallback(btDynamicsWorld *world, btScalar timeStep);
+ friend class BulletPhysicsDirectSpaceState;
+
+ btBroadphaseInterface *broadphase;
+ btDefaultCollisionConfiguration *collisionConfiguration;
+ btCollisionDispatcher *dispatcher;
+ btConstraintSolver *solver;
+ btDiscreteDynamicsWorld *dynamicsWorld;
+ btGhostPairCallback *ghostPairCallback;
+ GodotFilterCallback *godotFilterCallback;
+ btSoftBodyWorldInfo *soft_body_world_info;
+
+ btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver;
+ btVoronoiSimplexSolver *gjk_simplex_solver;
+
+ BulletPhysicsDirectSpaceState *direct_access;
+ Vector3 gravityDirection;
+ real_t gravityMagnitude;
+
+ Vector<AreaBullet *> areas;
+
+ Vector<Vector3> contactDebug;
+ int contactDebugCount;
+
+public:
+ SpaceBullet(bool p_create_soft_world);
+ virtual ~SpaceBullet();
+
+ void flush_queries();
+ void step(real_t p_delta_time);
+
+ _FORCE_INLINE_ btBroadphaseInterface *get_broadphase() { return broadphase; }
+ _FORCE_INLINE_ btCollisionDispatcher *get_dispatcher() { return dispatcher; }
+ _FORCE_INLINE_ btSoftBodyWorldInfo *get_soft_body_world_info() { 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(PhysicsServer::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(PhysicsServer::AreaParameter p_param);
+
+ void set_param(PhysicsServer::SpaceParameter p_param, real_t p_value);
+ real_t get_param(PhysicsServer::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(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.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[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();
+
+ bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result);
+
+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;
+ btVector3 pointNormalWorld;
+ btVector3 pointWorld;
+ btScalar penetration_distance; // Negative is penetration
+ int other_compound_shape_index;
+ const btCollisionObject *other_collision_object;
+ int local_shape_most_recovered;
+
+ RecoverResult()
+ : hasPenetration(false) {}
+ };
+
+ bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btVector3 &out_recover_position, RecoverResult *recover_result = NULL);
+};
+#endif
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index ba4163aab7..88588417d1 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -12,7 +12,8 @@ gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
-SConscript("nativearvr/SCsub")
+SConscript("arvr/SCsub")
+SConscript("pluginscript/SCsub")
def _spaced(e):
return e if e[-1] == '*' else e + ' '
@@ -24,8 +25,9 @@ def _build_gdnative_api_struct_header(api):
'#define GODOT_GDNATIVE_API_STRUCT_H',
'',
'#include <gdnative/gdnative.h>',
- '#include <nativearvr/godot_nativearvr.h>',
+ '#include <arvr/godot_arvr.h>',
'#include <nativescript/godot_nativescript.h>',
+ '#include <pluginscript/godot_pluginscript.h>',
'',
'#define GDNATIVE_API_INIT(options) do { extern const godot_gdnative_api_struct *_gdnative_wrapper_api_struct; _gdnative_wrapper_api_struct = options->api_struct; } while (0)',
'',
@@ -33,17 +35,55 @@ def _build_gdnative_api_struct_header(api):
'extern "C" {',
'#endif',
'',
+ 'typedef struct godot_gdnative_api_version {',
+ '\tunsigned int major;',
+ '\tunsigned int minor;',
+ '} godot_gdnative_api_version;',
+ '',
'typedef struct godot_gdnative_api_struct {',
- '\tvoid *next;',
- '\tconst char *version;',
+ '\tunsigned int type;',
+ '\tgodot_gdnative_api_version version;',
+ '\tconst godot_gdnative_api_struct *next;',
+ '} godot_gdnative_api_struct;',
+ '',
+ 'enum GDNATIVE_API_TYPES {',
+ '\tGDNATIVE_' + api['core']['type'] + ','
]
- for funcdef in api['api']:
+ for name in api['extensions']:
+ out += ['\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',']
+
+ out += ['};', '']
+
+ for name in api['extensions']:
+ out += [
+ 'typedef struct godot_gdnative_ext_' + name + '_api_struct {',
+ '\tunsigned int type;',
+ '\tgodot_gdnative_api_version version;',
+ '\tconst godot_gdnative_api_struct *next;'
+ ]
+
+ for funcdef in api['extensions'][name]['api']:
+ args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
+ out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
+
+ out += ['} godot_gdnative_ext_' + name + '_api_struct;', '']
+
+ out += [
+ 'typedef struct godot_gdnative_core_api_struct {',
+ '\tunsigned int type;',
+ '\tgodot_gdnative_api_version version;',
+ '\tconst godot_gdnative_api_struct *next;',
+ '\tunsigned int num_extensions;',
+ '\tconst godot_gdnative_api_struct **extensions;',
+ ]
+
+ for funcdef in api['core']['api']:
args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
out += [
- '} godot_gdnative_api_struct;',
+ '} godot_gdnative_core_api_struct;',
'',
'#ifdef __cplusplus',
'}',
@@ -59,14 +99,39 @@ def _build_gdnative_api_struct_source(api):
'/* THIS FILE IS GENERATED DO NOT EDIT */',
'',
'#include <gdnative_api_struct.gen.h>',
- '',
- 'const char *_gdnative_api_version = "%s";' % api['version'],
- 'extern const godot_gdnative_api_struct api_struct = {',
+ ''
+ ]
+
+ for name in api['extensions']:
+ out += [
+ 'extern const godot_gdnative_ext_' + name + '_api_struct api_extension_' + name + '_struct = {',
+ '\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',',
+ '\t{' + str(api['extensions'][name]['version']['major']) + ', ' + str(api['extensions'][name]['version']['minor']) + '},',
+ '\tNULL,'
+ ]
+
+ for funcdef in api['extensions'][name]['api']:
+ out.append('\t%s,' % funcdef['name'])
+
+ out += ['};\n']
+
+ out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {']
+
+ for name in api['extensions']:
+ out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,']
+
+ out += ['};\n']
+
+ out += [
+ 'extern const godot_gdnative_core_api_struct api_struct = {',
+ '\tGDNATIVE_' + api['core']['type'] + ',',
+ '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},',
'\tNULL,',
- '\t_gdnative_api_version,',
+ '\t' + str(len(api['extensions'])) + ',',
+ '\tgdnative_extensions_pointers,',
]
- for funcdef in api['api']:
+ for funcdef in api['core']['api']:
out.append('\t%s,' % funcdef['name'])
out.append('};\n')
@@ -98,6 +163,7 @@ def _build_gdnative_wrapper_code(api):
'',
'#include <gdnative/gdnative.h>',
'#include <nativescript/godot_nativescript.h>',
+ '#include <pluginscript/godot_pluginscript.h>',
'',
'#include <gdnative_api_struct.gen.h>',
'',
diff --git a/modules/gdnative/nativearvr/SCsub b/modules/gdnative/arvr/SCsub
index ecc5996108..ecc5996108 100644
--- a/modules/gdnative/nativearvr/SCsub
+++ b/modules/gdnative/arvr/SCsub
diff --git a/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp
index 78b0d1eadd..02f2ee7424 100644
--- a/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp
+++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp
@@ -39,6 +39,8 @@ ARVRInterfaceGDNative::ARVRInterfaceGDNative() {
// we won't have our data pointer until our library gets set
data = NULL;
+
+ interface = NULL;
}
ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
@@ -53,38 +55,35 @@ ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
}
void ARVRInterfaceGDNative::cleanup() {
- if (data != NULL) {
- library->call_native_raw("arvr_call_destructor", "godot_arvr_destructor", data, 0, NULL, NULL);
+ if (interface != NULL) {
+ interface->destructor(data);
data = NULL;
- };
-
- if (library.is_valid()) {
- library->terminate();
- };
-};
+ interface = NULL;
+ }
+}
-void ARVRInterfaceGDNative::set_gdnative_library(Ref<GDNativeLibrary> p_library) {
- if (library.is_null()) {
- library.instance();
- } else {
+void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p_interface) {
+ // this should only be called once, just being paranoid..
+ if (interface) {
cleanup();
- };
+ }
- library->set_library(p_library);
- library->initialize();
+ // bind to our interface
+ interface = p_interface;
// Now we do our constructing...
- void *parameters[1];
- parameters[0] = (void *)this;
- library->call_native_raw("arvr_call_constructor", "godot_arvr_constructor", NULL, 1, parameters, &data);
+ data = interface->constructor((godot_object *)this);
}
StringName ARVRInterfaceGDNative::get_name() const {
- StringName name;
- ERR_FAIL_COND_V(data == NULL, StringName());
+ ERR_FAIL_COND_V(interface == NULL, StringName());
+
+ godot_string result = interface->get_name(data);
- const_cast<GDNative *>(library.ptr())->call_native_raw("arvr_return_string", "godot_arvr_get_name", data, 0, NULL, &name);
+ StringName name = *(String *)&result;
+
+ godot_string_destroy(&result);
return name;
}
@@ -92,58 +91,56 @@ StringName ARVRInterfaceGDNative::get_name() const {
int ARVRInterfaceGDNative::get_capabilities() const {
int capabilities;
- ERR_FAIL_COND_V(data == NULL, 0); // 0 = None
+ ERR_FAIL_COND_V(interface == NULL, 0); // 0 = None
- const_cast<GDNative *>(library.ptr())->call_native_raw("arvr_return_int", "godot_arvr_get_capabilities", data, 0, NULL, &capabilities);
+ capabilities = interface->get_capabilities(data);
return capabilities;
-};
+}
bool ARVRInterfaceGDNative::get_anchor_detection_is_enabled() const {
bool enabled;
- ERR_FAIL_COND_V(data == NULL, false);
+ ERR_FAIL_COND_V(interface == NULL, false);
- const_cast<GDNative *>(library.ptr())->call_native_raw("arvr_return_bool", "godot_arvr_get_anchor_detection_is_enabled", data, 0, NULL, &enabled);
+ enabled = interface->get_anchor_detection_is_enabled(data);
return enabled;
-};
+}
void ARVRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
- void *parameters[1];
- ERR_FAIL_COND(data == NULL);
+ ERR_FAIL_COND(interface == NULL);
- parameters[0] = (void *)&p_enable;
- library->call_native_raw("arvr_set_bool", "godot_arvr_set_anchor_detection_is_enabled", data, 1, parameters, NULL);
-};
+ interface->set_anchor_detection_is_enabled(data, p_enable);
+}
bool ARVRInterfaceGDNative::is_stereo() {
bool stereo;
- ERR_FAIL_COND_V(data == NULL, false);
+ ERR_FAIL_COND_V(interface == NULL, false);
- library->call_native_raw("arvr_return_bool", "godot_arvr_is_stereo", data, 0, NULL, &stereo);
+ stereo = interface->is_stereo(data);
return stereo;
-};
+}
bool ARVRInterfaceGDNative::is_initialized() {
bool initialized;
- ERR_FAIL_COND_V(data == NULL, false);
+ ERR_FAIL_COND_V(interface == NULL, false);
- library->call_native_raw("arvr_return_bool", "godot_arvr_is_initialized", data, 0, NULL, &initialized);
+ initialized = interface->is_initialized(data);
return initialized;
-};
+}
bool ARVRInterfaceGDNative::initialize() {
bool initialized;
- ERR_FAIL_COND_V(data == NULL, false);
+ ERR_FAIL_COND_V(interface == NULL, false);
- library->call_native_raw("arvr_return_bool", "godot_arvr_initialize", data, 0, NULL, &initialized);
+ initialized = interface->initialize(data);
if (initialized) {
// if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface
@@ -158,7 +155,7 @@ bool ARVRInterfaceGDNative::initialize() {
}
void ARVRInterfaceGDNative::uninitialize() {
- ERR_FAIL_COND(data == NULL);
+ ERR_FAIL_COND(interface == NULL);
ARVRServer *arvr_server = ARVRServer::get_singleton();
if (arvr_server != NULL) {
@@ -166,78 +163,72 @@ void ARVRInterfaceGDNative::uninitialize() {
arvr_server->clear_primary_interface_if(this);
}
- library->call_native_raw("arvr_call_method", "godot_arvr_uninitialize", data, 0, NULL, NULL);
+ interface->uninitialize(data);
}
-Size2 ARVRInterfaceGDNative::get_recommended_render_targetsize() {
- Size2 size;
+Size2 ARVRInterfaceGDNative::get_render_targetsize() {
- ERR_FAIL_COND_V(data == NULL, Size2());
+ ERR_FAIL_COND_V(interface == NULL, Size2());
- library->call_native_raw("arvr_return_vector2", "godot_arvr_get_recommended_render_targetsize", data, 0, NULL, &size);
+ godot_vector2 result = interface->get_render_targetsize(data);
+ Vector2 *vec = (Vector2 *)&result;
- return size;
+ return *vec;
}
Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
- void *parameters[2];
- Transform ret;
+ Transform *ret;
- ERR_FAIL_COND_V(data == NULL, Transform());
+ ERR_FAIL_COND_V(interface == NULL, Transform());
- parameters[0] = (void *)&p_eye;
- parameters[1] = (void *)&p_cam_transform;
- library->call_native_raw("arvr_return_transform_for_eye", "godot_arvr_get_transform_for_eye", data, 2, parameters, &ret);
+ godot_transform t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform *)&p_cam_transform);
- return ret;
+ ret = (Transform *)&t;
+
+ return *ret;
}
CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
- void *parameters[5];
CameraMatrix cm;
- ERR_FAIL_COND_V(data == NULL, CameraMatrix());
+ ERR_FAIL_COND_V(interface == NULL, CameraMatrix());
- parameters[0] = (void *)cm.matrix;
- parameters[1] = (void *)&p_eye;
- parameters[2] = (void *)&p_aspect;
- parameters[3] = (void *)&p_z_near;
- parameters[4] = (void *)&p_z_far;
- library->call_native_raw("arvr_call_fill_projection_for_eye", "godot_arvr_fill_projection_for_eye", data, 5, parameters, NULL);
+ interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
return cm;
}
void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
- void *parameters[3];
- ERR_FAIL_COND(data == NULL);
+ ERR_FAIL_COND(interface == NULL);
- parameters[0] = (void *)&p_eye;
- parameters[1] = (void *)&p_render_target;
- parameters[2] = (void *)&p_screen_rect;
- library->call_native_raw("arvr_call_commit_for_eye", "godot_arvr_commit_for_eye", data, 3, parameters, NULL);
+ interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
}
void ARVRInterfaceGDNative::process() {
- ERR_FAIL_COND(data == NULL);
-
- library->call_native_raw("arvr_call_method", "godot_arvr_process", data, 0, NULL, NULL);
-}
+ ERR_FAIL_COND(interface == NULL);
-void ARVRInterfaceGDNative::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_gdnative_library", "library"), &ARVRInterfaceGDNative::set_gdnative_library);
+ interface->process(data);
}
/////////////////////////////////////////////////////////////////////////////////////
// some helper callbacks
+extern "C" {
+
+void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) {
+ Ref<ARVRInterfaceGDNative> new_interface;
+ new_interface.instance();
+ new_interface->set_interface((godot_arvr_interface_gdnative * const)p_interface);
+ ARVRServer::get_singleton()->add_interface(new_interface);
+}
+
godot_real GDAPI godot_arvr_get_worldscale() {
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL_V(arvr_server, 1.0);
return arvr_server->get_world_scale();
-};
+}
godot_transform GDAPI godot_arvr_get_reference_frame() {
godot_transform reference_frame;
@@ -248,10 +239,10 @@ godot_transform GDAPI godot_arvr_get_reference_frame() {
*reference_frame_ptr = arvr_server->get_reference_frame();
} else {
godot_transform_new_identity(&reference_frame);
- };
+ }
return reference_frame;
-};
+}
void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
// blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD
@@ -268,7 +259,7 @@ void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_re
VSG::rasterizer->set_current_render_target(RID());
VSG::rasterizer->blit_render_target_to_screen(*render_target, screen_rect, 0);
-};
+}
godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
// In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID
@@ -279,7 +270,7 @@ godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
uint32_t texid = VS::get_singleton()->texture_get_texid(eye_texture);
return texid;
-};
+}
godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
ARVRServer *arvr_server = ARVRServer::get_singleton();
@@ -295,30 +286,30 @@ godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand,
new_tracker->set_hand(ARVRPositionalTracker::TRACKER_LEFT_HAND);
} else if (p_hand == 2) {
new_tracker->set_hand(ARVRPositionalTracker::TRACKER_RIGHT_HAND);
- };
+ }
// also register as joystick...
int joyid = input->get_unused_joy_id();
if (joyid != -1) {
new_tracker->set_joy_id(joyid);
input->joy_connection_changed(joyid, true, p_device_name, "");
- };
+ }
if (p_tracks_orientation) {
Basis orientation;
new_tracker->set_orientation(orientation);
- };
+ }
if (p_tracks_position) {
Vector3 position;
new_tracker->set_position(position);
- };
+ }
// add our tracker to our server and remember its pointer
arvr_server->add_tracker(new_tracker);
// note, this ID is only unique within controllers!
return new_tracker->get_tracker_id();
-};
+}
void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
ARVRServer *arvr_server = ARVRServer::get_singleton();
@@ -334,13 +325,13 @@ void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
if (joyid != -1) {
input->joy_connection_changed(joyid, false, "", "");
remove_tracker->set_joy_id(-1);
- };
+ }
// remove our tracker from our server
arvr_server->remove_tracker(remove_tracker);
memdelete(remove_tracker);
- };
-};
+ }
+}
void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
ARVRServer *arvr_server = ARVRServer::get_singleton();
@@ -351,12 +342,12 @@ void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_
Transform *transform = (Transform *)p_transform;
if (p_tracks_orientation) {
tracker->set_orientation(transform->basis);
- };
+ }
if (p_tracks_position) {
tracker->set_position(transform->origin);
- };
- };
-};
+ }
+ }
+}
void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
ARVRServer *arvr_server = ARVRServer::get_singleton();
@@ -370,9 +361,9 @@ void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int
int joyid = tracker->get_joy_id();
if (joyid != -1) {
input->joy_button(joyid, p_button, p_is_pressed);
- };
- };
-};
+ }
+ }
+}
void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
ARVRServer *arvr_server = ARVRServer::get_singleton();
@@ -389,6 +380,19 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p
jx.min = p_can_be_negative ? -1 : 0;
jx.value = p_value;
input->joy_axis(joyid, p_axis, jx);
- };
- };
-};
+ }
+ }
+}
+
+godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, 0.0);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != NULL) {
+ return tracker->get_rumble();
+ }
+
+ return 0.0;
+}
+}
diff --git a/modules/gdnative/nativearvr/arvr_interface_gdnative.h b/modules/gdnative/arvr/arvr_interface_gdnative.h
index 6995e85c73..96f7b580d5 100644
--- a/modules/gdnative/nativearvr/arvr_interface_gdnative.h
+++ b/modules/gdnative/arvr/arvr_interface_gdnative.h
@@ -41,22 +41,20 @@
*/
class ARVRInterfaceGDNative : public ARVRInterface {
- GDCLASS(ARVRInterfaceGDNative, ARVRInterface);
+ GDCLASS(ARVRInterfaceGDNative, ARVRInterface)
void cleanup();
protected:
- Ref<GDNative> library;
+ const godot_arvr_interface_gdnative *interface;
void *data;
- static void _bind_methods();
-
public:
/** general interface information **/
ARVRInterfaceGDNative();
~ARVRInterfaceGDNative();
- void set_gdnative_library(Ref<GDNativeLibrary> p_library);
+ void set_interface(const godot_arvr_interface_gdnative *p_interface);
virtual StringName get_name() const;
virtual int get_capabilities() const;
@@ -70,7 +68,7 @@ public:
virtual void set_anchor_detection_is_enabled(bool p_enable);
/** rendering and internal **/
- virtual Size2 get_recommended_render_targetsize();
+ virtual Size2 get_render_targetsize();
virtual bool is_stereo();
virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
diff --git a/modules/gdnative/nativearvr/config.py b/modules/gdnative/arvr/config.py
index 4d1bdfe4d1..4d1bdfe4d1 100644
--- a/modules/gdnative/nativearvr/config.py
+++ b/modules/gdnative/arvr/config.py
diff --git a/modules/gdnative/arvr/register_types.cpp b/modules/gdnative/arvr/register_types.cpp
new file mode 100644
index 0000000000..139750a02d
--- /dev/null
+++ b/modules/gdnative/arvr/register_types.cpp
@@ -0,0 +1,39 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "arvr_interface_gdnative.h"
+
+void register_arvr_types() {
+ ClassDB::register_class<ARVRInterfaceGDNative>();
+}
+
+void unregister_arvr_types() {
+}
diff --git a/modules/gdnative/nativearvr/register_types.h b/modules/gdnative/arvr/register_types.h
index 5e7557c7e9..4918319926 100644
--- a/modules/gdnative/nativearvr/register_types.h
+++ b/modules/gdnative/arvr/register_types.h
@@ -28,5 +28,5 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_nativearvr_types();
-void unregister_nativearvr_types();
+void register_arvr_types();
+void unregister_arvr_types();
diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
index 74f71ff603..308a7d5946 100644
--- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
+++ b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
@@ -11,15 +11,6 @@
<demos>
</demos>
<methods>
- <method name="set_gdnative_library">
- <return type="void">
- </return>
- <argument index="0" name="library" type="GDNativeLibrary">
- </argument>
- <description>
- Bind this GDNative library to our interface. The library must be a GDNative ARVR Interface for this to work.
- </description>
- </method>
</methods>
<constants>
</constants>
diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml
index ba813c4564..83a1cf06f0 100644
--- a/modules/gdnative/doc_classes/GDNative.xml
+++ b/modules/gdnative/doc_classes/GDNative.xml
@@ -12,11 +12,11 @@
<method name="call_native">
<return type="Variant">
</return>
- <argument index="0" name="procedure_name" type="String">
+ <argument index="0" name="calling_type" type="String">
</argument>
- <argument index="1" name="arguments" type="String">
+ <argument index="1" name="procedure_name" type="String">
</argument>
- <argument index="2" name="arg2" type="Array">
+ <argument index="2" name="arguments" type="Array">
</argument>
<description>
</description>
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 373b98dc8b..832a0cb859 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -41,7 +41,7 @@ const String init_symbol = "godot_gdnative_init";
const String terminate_symbol = "godot_gdnative_terminate";
// Defined in gdnative_api_struct.gen.cpp
-extern const godot_gdnative_api_struct api_struct;
+extern const godot_gdnative_core_api_struct api_struct;
String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = {
"X11_32bit",
@@ -199,10 +199,7 @@ void GDNative::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialize"), &GDNative::initialize);
ClassDB::bind_method(D_METHOD("terminate"), &GDNative::terminate);
- // TODO(karroffel): get_native_(raw_)call_types binding?
-
- // TODO(karroffel): make this a varargs function?
- ClassDB::bind_method(D_METHOD("call_native", "procedure_name", "arguments"), &GDNative::call_native);
+ ClassDB::bind_method(D_METHOD("call_native", "calling_type", "procedure_name", "arguments"), &GDNative::call_native);
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "GDNativeLibrary"), "set_library", "get_library");
}
@@ -239,10 +236,7 @@ bool GDNative::initialize() {
}
void *library_init;
- err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- native_handle,
- init_symbol,
- library_init);
+ err = get_symbol(init_symbol, library_init);
if (err || !library_init) {
OS::get_singleton()->close_dynamic_library(native_handle);
@@ -277,11 +271,8 @@ bool GDNative::terminate() {
}
void *library_terminate;
- Error error = OS::get_singleton()->get_dynamic_library_symbol_handle(
- native_handle,
- terminate_symbol,
- library_terminate);
- if (error) {
+ Error error = get_symbol(terminate_symbol, library_terminate);
+ if (error || !library_terminate) {
OS::get_singleton()->close_dynamic_library(native_handle);
native_handle = NULL;
return true;
@@ -313,10 +304,6 @@ void GDNativeCallRegistry::register_native_call_type(StringName p_call_type, nat
native_calls.insert(p_call_type, p_callback);
}
-void GDNativeCallRegistry::register_native_raw_call_type(StringName p_raw_call_type, native_raw_call_cb p_callback) {
- native_raw_calls.insert(p_raw_call_type, p_callback);
-}
-
Vector<StringName> GDNativeCallRegistry::get_native_call_types() {
Vector<StringName> call_types;
call_types.resize(native_calls.size());
@@ -329,18 +316,6 @@ Vector<StringName> GDNativeCallRegistry::get_native_call_types() {
return call_types;
}
-Vector<StringName> GDNativeCallRegistry::get_native_raw_call_types() {
- Vector<StringName> call_types;
- call_types.resize(native_raw_calls.size());
-
- size_t idx = 0;
- for (Map<StringName, native_raw_call_cb>::Element *E = native_raw_calls.front(); E; E = E->next(), idx++) {
- call_types[idx] = E->key();
- }
-
- return call_types;
-}
-
Variant GDNative::call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments) {
Map<StringName, native_call_cb>::Element *E = GDNativeCallRegistry::singleton->native_calls.find(p_native_call_type);
@@ -349,20 +324,34 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced
return Variant();
}
- String procedure_name = p_procedure_name;
- godot_variant result = E->get()(native_handle, (godot_string *)&procedure_name, (godot_array *)&p_arguments);
+ void *procedure_handle;
+
+ Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
+ native_handle,
+ p_procedure_name,
+ procedure_handle);
+
+ if (err != OK || procedure_handle == NULL) {
+ return Variant();
+ }
+
+ godot_variant result = E->get()(procedure_handle, (godot_array *)&p_arguments);
return *(Variant *)&result;
}
-void GDNative::call_native_raw(StringName p_raw_call_type, StringName p_procedure_name, void *data, int num_args, void **args, void *r_return) {
+Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) {
- Map<StringName, native_raw_call_cb>::Element *E = GDNativeCallRegistry::singleton->native_raw_calls.find(p_raw_call_type);
- if (!E) {
- ERR_PRINT((String("No handler for native raw call type \"" + p_raw_call_type) + "\" found").utf8().get_data());
- return;
+ if (native_handle == NULL) {
+ ERR_PRINT("No valid library handle, can't get symbol from GDNative object");
+ return ERR_CANT_OPEN;
}
- String procedure_name = p_procedure_name;
- E->get()(native_handle, (godot_string *)&procedure_name, data, num_args, args, r_return);
+ Error result = OS::get_singleton()->get_dynamic_library_symbol_handle(
+ native_handle,
+ p_procedure_name,
+ r_handle,
+ true);
+
+ return result;
}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 7bbad842eb..e44cc55a79 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -100,8 +100,7 @@ public:
_FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; }
};
-typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *);
-typedef void (*native_raw_call_cb)(void *, godot_string *, void *, int, void **, void *);
+typedef godot_variant (*native_call_cb)(void *, godot_array *);
struct GDNativeCallRegistry {
static GDNativeCallRegistry *singleton;
@@ -111,17 +110,13 @@ struct GDNativeCallRegistry {
}
inline GDNativeCallRegistry()
- : native_calls(),
- native_raw_calls() {}
+ : native_calls() {}
Map<StringName, native_call_cb> native_calls;
- Map<StringName, native_raw_call_cb> native_raw_calls;
void register_native_call_type(StringName p_call_type, native_call_cb p_callback);
- void register_native_raw_call_type(StringName p_raw_call_type, native_raw_call_cb p_callback);
Vector<StringName> get_native_call_types();
- Vector<StringName> get_native_raw_call_types();
};
class GDNative : public Reference {
@@ -149,7 +144,8 @@ public:
bool terminate();
Variant call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments = Array());
- void call_native_raw(StringName p_raw_call_type, StringName p_procedure_name, void *data, int num_args, void **args, void *r_return);
+
+ Error get_symbol(StringName p_procedure_name, void *&r_handle);
};
#endif // GDNATIVE_H
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 51c023981f..90bc4dc031 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -158,6 +158,11 @@ godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot
return (godot_variant *)&self->operator[](p_idx);
}
+const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx) {
+ const Array *self = (const Array *)p_self;
+ return (const godot_variant *)&self->operator[](p_idx);
+}
+
void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value) {
Array *self = (Array *)p_self;
Variant *val = (Variant *)p_value;
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index b1327cdaef..28af93f942 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -172,7 +172,7 @@ void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat
}
// p_elements is a pointer to an array of 3 (!!) vector3
-void GDAPI godot_basis_get_elements(godot_basis *p_self, godot_vector3 *p_elements) {
+void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements) {
const Basis *self = (const Basis *)p_self;
Vector3 *elements = (Vector3 *)p_elements;
elements[0] = self->elements[0];
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index ed98cdbb00..7f8320622d 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -130,6 +130,12 @@ godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, c
return (godot_variant *)&self->operator[](*key);
}
+const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ return (const godot_variant *)&self->operator[](*key);
+}
+
godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key) {
Dictionary *self = (Dictionary *)p_self;
const Variant *key = (const Variant *)p_key;
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index 1393374da2..731e930908 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -106,6 +106,16 @@ void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const god
self->resize(p_size);
}
+godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read(const godot_pool_byte_array *p_self) {
+ const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+ return (godot_pool_byte_array_read_access *)memnew(PoolVector<uint8_t>::Read(self->read()));
+}
+
+godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write(godot_pool_byte_array *p_self) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ return (godot_pool_byte_array_write_access *)memnew(PoolVector<uint8_t>::Write(self->write()));
+}
+
void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
self->set(p_idx, p_data);
@@ -185,6 +195,16 @@ void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot
self->resize(p_size);
}
+godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read(const godot_pool_int_array *p_self) {
+ const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+ return (godot_pool_int_array_read_access *)memnew(PoolVector<godot_int>::Read(self->read()));
+}
+
+godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write(godot_pool_int_array *p_self) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ return (godot_pool_int_array_write_access *)memnew(PoolVector<godot_int>::Write(self->write()));
+}
+
void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
self->set(p_idx, p_data);
@@ -260,10 +280,20 @@ void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const god
}
void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
self->resize(p_size);
}
+godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read(const godot_pool_real_array *p_self) {
+ const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+ return (godot_pool_real_array_read_access *)memnew(PoolVector<godot_real>::Read(self->read()));
+}
+
+godot_pool_int_array_write_access GDAPI *godot_pool_real_array_write(godot_pool_real_array *p_self) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ return (godot_pool_real_array_write_access *)memnew(PoolVector<godot_real>::Write(self->write()));
+}
+
void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
self->set(p_idx, p_data);
@@ -346,6 +376,16 @@ void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const
self->resize(p_size);
}
+godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read(const godot_pool_string_array *p_self) {
+ const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+ return (godot_pool_string_array_read_access *)memnew(PoolVector<String>::Read(self->read()));
+}
+
+godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write(godot_pool_string_array *p_self) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
+ return (godot_pool_string_array_write_access *)memnew(PoolVector<String>::Write(self->write()));
+}
+
void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
PoolVector<String> *self = (PoolVector<String> *)p_self;
String &s = *(String *)p_data;
@@ -433,6 +473,16 @@ void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, con
self->resize(p_size);
}
+godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read(const godot_pool_vector2_array *p_self) {
+ const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+ return (godot_pool_vector2_array_read_access *)memnew(PoolVector<Vector2>::Read(self->read()));
+}
+
+godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write(godot_pool_vector2_array *p_self) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+ return (godot_pool_vector2_array_write_access *)memnew(PoolVector<Vector2>::Write(self->write()));
+}
+
void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
@@ -519,6 +569,16 @@ void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, con
self->resize(p_size);
}
+godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read(const godot_pool_vector3_array *p_self) {
+ const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+ return (godot_pool_vector3_array_read_access *)memnew(PoolVector<Vector3>::Read(self->read()));
+}
+
+godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write(godot_pool_vector3_array *p_self) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+ return (godot_pool_vector3_array_write_access *)memnew(PoolVector<Vector3>::Write(self->write()));
+}
+
void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
@@ -605,6 +665,16 @@ void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const g
self->resize(p_size);
}
+godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read(const godot_pool_color_array *p_self) {
+ const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+ return (godot_pool_color_array_read_access *)memnew(PoolVector<Color>::Read(self->read()));
+}
+
+godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write(godot_pool_color_array *p_self) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+ return (godot_pool_color_array_write_access *)memnew(PoolVector<Color>::Write(self->write()));
+}
+
void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
PoolVector<Color> *self = (PoolVector<Color> *)p_self;
Color &s = *(Color *)p_data;
@@ -628,6 +698,196 @@ void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self) {
((PoolVector<Color> *)p_self)->~PoolVector();
}
+//
+// read accessor functions
+//
+
+const uint8_t GDAPI *godot_pool_byte_array_read_access_ptr(const godot_pool_byte_array_read_access *p_read) {
+ const PoolVector<uint8_t>::Read *read = (const PoolVector<uint8_t>::Read *)p_read;
+ return read->ptr();
+}
+void GDAPI godot_pool_byte_array_read_access_operator_assign(godot_pool_byte_array_read_access *p_read, godot_pool_byte_array_read_access *p_other) {
+ PoolVector<uint8_t>::Read *read = (PoolVector<uint8_t>::Read *)p_read;
+ PoolVector<uint8_t>::Read *other = (PoolVector<uint8_t>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_byte_array_read_access_destroy(godot_pool_byte_array_read_access *p_read) {
+ memdelete((PoolVector<uint8_t>::Read *)p_read);
+}
+
+const godot_int GDAPI *godot_pool_int_array_read_access_ptr(const godot_pool_int_array_read_access *p_read) {
+ const PoolVector<godot_int>::Read *read = (const PoolVector<godot_int>::Read *)p_read;
+ return read->ptr();
+}
+void GDAPI godot_pool_int_array_read_access_operator_assign(godot_pool_int_array_read_access *p_read, godot_pool_int_array_read_access *p_other) {
+ PoolVector<godot_int>::Read *read = (PoolVector<godot_int>::Read *)p_read;
+ PoolVector<godot_int>::Read *other = (PoolVector<godot_int>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_int_array_read_access_destroy(godot_pool_int_array_read_access *p_read) {
+ memdelete((PoolVector<godot_int>::Read *)p_read);
+}
+
+const godot_real GDAPI *godot_pool_real_array_read_access_ptr(const godot_pool_real_array_read_access *p_read) {
+ const PoolVector<godot_real>::Read *read = (const PoolVector<godot_real>::Read *)p_read;
+ return read->ptr();
+}
+void GDAPI godot_pool_real_array_read_access_operator_assign(godot_pool_real_array_read_access *p_read, godot_pool_real_array_read_access *p_other) {
+ PoolVector<godot_real>::Read *read = (PoolVector<godot_real>::Read *)p_read;
+ PoolVector<godot_real>::Read *other = (PoolVector<godot_real>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_real_array_read_access_destroy(godot_pool_real_array_read_access *p_read) {
+ memdelete((PoolVector<godot_real>::Read *)p_read);
+}
+
+const godot_string GDAPI *godot_pool_string_array_read_access_ptr(const godot_pool_string_array_read_access *p_read) {
+ const PoolVector<String>::Read *read = (const PoolVector<String>::Read *)p_read;
+ return (const godot_string *)read->ptr();
+}
+void GDAPI godot_pool_string_array_read_access_operator_assign(godot_pool_string_array_read_access *p_read, godot_pool_string_array_read_access *p_other) {
+ PoolVector<String>::Read *read = (PoolVector<String>::Read *)p_read;
+ PoolVector<String>::Read *other = (PoolVector<String>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_string_array_read_access_destroy(godot_pool_string_array_read_access *p_read) {
+ memdelete((PoolVector<String>::Read *)p_read);
+}
+
+const godot_vector2 GDAPI *godot_pool_vector2_array_read_access_ptr(const godot_pool_vector2_array_read_access *p_read) {
+ const PoolVector<Vector2>::Read *read = (const PoolVector<Vector2>::Read *)p_read;
+ return (const godot_vector2 *)read->ptr();
+}
+void GDAPI godot_pool_vector2_array_read_access_operator_assign(godot_pool_vector2_array_read_access *p_read, godot_pool_vector2_array_read_access *p_other) {
+ PoolVector<Vector2>::Read *read = (PoolVector<Vector2>::Read *)p_read;
+ PoolVector<Vector2>::Read *other = (PoolVector<Vector2>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_vector2_array_read_access_destroy(godot_pool_vector2_array_read_access *p_read) {
+ memdelete((PoolVector<Vector2>::Read *)p_read);
+}
+
+const godot_vector3 GDAPI *godot_pool_vector3_array_read_access_ptr(const godot_pool_vector3_array_read_access *p_read) {
+ const PoolVector<Vector3>::Read *read = (const PoolVector<Vector3>::Read *)p_read;
+ return (const godot_vector3 *)read->ptr();
+}
+void GDAPI godot_pool_vector3_array_read_access_operator_assign(godot_pool_vector3_array_read_access *p_read, godot_pool_vector3_array_read_access *p_other) {
+ PoolVector<Vector3>::Read *read = (PoolVector<Vector3>::Read *)p_read;
+ PoolVector<Vector3>::Read *other = (PoolVector<Vector3>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_vector3_array_read_access_destroy(godot_pool_vector3_array_read_access *p_read) {
+ memdelete((PoolVector<Vector2>::Read *)p_read);
+}
+
+const godot_color GDAPI *godot_pool_color_array_read_access_ptr(const godot_pool_color_array_read_access *p_read) {
+ const PoolVector<Color>::Read *read = (const PoolVector<Color>::Read *)p_read;
+ return (const godot_color *)read->ptr();
+}
+void GDAPI godot_pool_color_array_read_access_operator_assign(godot_pool_color_array_read_access *p_read, godot_pool_color_array_read_access *p_other) {
+ PoolVector<Color>::Read *read = (PoolVector<Color>::Read *)p_read;
+ PoolVector<Color>::Read *other = (PoolVector<Color>::Read *)p_other;
+ read->operator=(*other);
+}
+void GDAPI godot_pool_color_array_read_access_destroy(godot_pool_color_array_read_access *p_read) {
+ memdelete((PoolVector<Color>::Read *)p_read);
+}
+
+//
+// write accessor functions
+//
+
+uint8_t GDAPI *godot_pool_byte_array_write_access_ptr(const godot_pool_byte_array_write_access *p_write) {
+ PoolVector<uint8_t>::Write *write = (PoolVector<uint8_t>::Write *)p_write;
+ return write->ptr();
+}
+void GDAPI godot_pool_byte_array_write_access_operator_assign(godot_pool_byte_array_write_access *p_write, godot_pool_byte_array_write_access *p_other) {
+ PoolVector<uint8_t>::Write *write = (PoolVector<uint8_t>::Write *)p_write;
+ PoolVector<uint8_t>::Write *other = (PoolVector<uint8_t>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_byte_array_write_access_destroy(godot_pool_byte_array_write_access *p_write) {
+ memdelete((PoolVector<uint8_t>::Write *)p_write);
+}
+
+godot_int GDAPI *godot_pool_int_array_write_access_ptr(const godot_pool_int_array_write_access *p_write) {
+ PoolVector<godot_int>::Write *write = (PoolVector<godot_int>::Write *)p_write;
+ return write->ptr();
+}
+void GDAPI godot_pool_int_array_write_access_operator_assign(godot_pool_int_array_write_access *p_write, godot_pool_int_array_write_access *p_other) {
+ PoolVector<godot_int>::Write *write = (PoolVector<godot_int>::Write *)p_write;
+ PoolVector<godot_int>::Write *other = (PoolVector<godot_int>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_int_array_write_access_destroy(godot_pool_int_array_write_access *p_write) {
+ memdelete((PoolVector<godot_int>::Write *)p_write);
+}
+
+godot_real GDAPI *godot_pool_real_array_write_access_ptr(const godot_pool_real_array_write_access *p_write) {
+ PoolVector<godot_real>::Write *write = (PoolVector<godot_real>::Write *)p_write;
+ return write->ptr();
+}
+void GDAPI godot_pool_real_array_write_access_operator_assign(godot_pool_real_array_write_access *p_write, godot_pool_real_array_write_access *p_other) {
+ PoolVector<godot_real>::Write *write = (PoolVector<godot_real>::Write *)p_write;
+ PoolVector<godot_real>::Write *other = (PoolVector<godot_real>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_real_array_write_access_destroy(godot_pool_real_array_write_access *p_write) {
+ memdelete((PoolVector<godot_real>::Write *)p_write);
+}
+
+godot_string GDAPI *godot_pool_string_array_write_access_ptr(const godot_pool_string_array_write_access *p_write) {
+ PoolVector<String>::Write *write = (PoolVector<String>::Write *)p_write;
+ return (godot_string *)write->ptr();
+}
+void GDAPI godot_pool_string_array_write_access_operator_assign(godot_pool_string_array_write_access *p_write, godot_pool_string_array_write_access *p_other) {
+ PoolVector<String>::Write *write = (PoolVector<String>::Write *)p_write;
+ PoolVector<String>::Write *other = (PoolVector<String>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_string_array_write_access_destroy(godot_pool_string_array_write_access *p_write) {
+ memdelete((PoolVector<String>::Write *)p_write);
+}
+
+godot_vector2 GDAPI *godot_pool_vector2_array_write_access_ptr(const godot_pool_vector2_array_write_access *p_write) {
+ PoolVector<Vector2>::Write *write = (PoolVector<Vector2>::Write *)p_write;
+ return (godot_vector2 *)write->ptr();
+}
+void GDAPI godot_pool_vector2_array_write_access_operator_assign(godot_pool_vector2_array_write_access *p_write, godot_pool_vector2_array_write_access *p_other) {
+ PoolVector<Vector2>::Write *write = (PoolVector<Vector2>::Write *)p_write;
+ PoolVector<Vector2>::Write *other = (PoolVector<Vector2>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_vector2_array_write_access_destroy(godot_pool_vector2_array_write_access *p_write) {
+ memdelete((PoolVector<Vector2>::Write *)p_write);
+}
+
+godot_vector3 GDAPI *godot_pool_vector3_array_write_access_ptr(const godot_pool_vector3_array_write_access *p_write) {
+ PoolVector<Vector3>::Write *write = (PoolVector<Vector3>::Write *)p_write;
+ return (godot_vector3 *)write->ptr();
+}
+void GDAPI godot_pool_vector3_array_write_access_operator_assign(godot_pool_vector3_array_write_access *p_write, godot_pool_vector3_array_write_access *p_other) {
+ PoolVector<Vector3>::Write *write = (PoolVector<Vector3>::Write *)p_write;
+ PoolVector<Vector3>::Write *other = (PoolVector<Vector3>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_vector3_array_write_access_destroy(godot_pool_vector3_array_write_access *p_write) {
+ memdelete((PoolVector<Vector3>::Write *)p_write);
+}
+
+godot_color GDAPI *godot_pool_color_array_write_access_ptr(const godot_pool_color_array_write_access *p_write) {
+ PoolVector<Color>::Write *write = (PoolVector<Color>::Write *)p_write;
+ return (godot_color *)write->ptr();
+}
+void GDAPI godot_pool_color_array_write_access_operator_assign(godot_pool_color_array_write_access *p_write, godot_pool_color_array_write_access *p_other) {
+ PoolVector<Color>::Write *write = (PoolVector<Color>::Write *)p_write;
+ PoolVector<Color>::Write *other = (PoolVector<Color>::Write *)p_other;
+ write->operator=(*other);
+}
+void GDAPI godot_pool_color_array_write_access_destroy(godot_pool_color_array_write_access *p_write) {
+ memdelete((PoolVector<Color>::Write *)p_write);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 9b715ce36a..619003083d 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "gdnative/string.h"
+#include "core/string_db.h"
+#include "core/ustring.h"
#include "core/variant.h"
-#include "string_db.h"
-#include "ustring.h"
#include <string.h>
@@ -65,11 +65,20 @@ void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_
void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int *p_size) {
String *self = (String *)p_self;
- if (p_size != NULL) {
- *p_size = self->utf8().length();
- }
- if (p_dest != NULL) {
- memcpy(p_dest, self->utf8().get_data(), *p_size);
+
+ if (p_size) {
+ // we have a length pointer, that means we either want to know
+ // the length or want to write *p_size bytes into a buffer
+
+ CharString utf8_string = self->utf8();
+
+ int len = utf8_string.length();
+
+ if (p_dest) {
+ memcpy(p_dest, utf8_string.get_data(), *p_size);
+ } else {
+ *p_size = len;
+ }
}
}
@@ -78,6 +87,11 @@ wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int
return &(self->operator[](p_idx));
}
+wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx) {
+ const String *self = (const String *)p_self;
+ return self->operator[](p_idx);
+}
+
const char GDAPI *godot_string_c_str(const godot_string *p_self) {
const String *self = (const String *)p_self;
return self->utf8().get_data();
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 5ebf26cbf7..770fb429c7 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -1,5306 +1,5792 @@
{
- "version": "1.0.0",
- "api": [
- {
- "name": "godot_color_new_rgba",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "r_dest"],
- ["const godot_real", "p_r"],
- ["const godot_real", "p_g"],
- ["const godot_real", "p_b"],
- ["const godot_real", "p_a"]
- ]
- },
- {
- "name": "godot_color_new_rgb",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "r_dest"],
- ["const godot_real", "p_r"],
- ["const godot_real", "p_g"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_color_get_r",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_r",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "r"]
- ]
- },
- {
- "name": "godot_color_get_g",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_g",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "g"]
- ]
- },
- {
- "name": "godot_color_get_b",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_b",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "b"]
- ]
- },
- {
- "name": "godot_color_get_a",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_a",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "a"]
- ]
- },
- {
- "name": "godot_color_get_h",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_get_s",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_get_v",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_rgba32",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_argb32",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_gray",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_inverted",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_contrasted",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_linear_interpolate",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_color_blend",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_over"]
- ]
- },
- {
- "name": "godot_color_to_html",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_bool", "p_with_alpha"]
- ]
- },
- {
- "name": "godot_color_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"]
- ]
- },
- {
- "name": "godot_color_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"]
- ]
- },
- {
- "name": "godot_vector2_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_normalized",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_angle",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_distance_squared_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_angle_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_angle_to_point",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_linear_interpolate",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector2_cubic_interpolate",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"],
- ["const godot_vector2 *", "p_pre_a"],
- ["const godot_vector2 *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector2_rotated",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_vector2_tangent",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_floor",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_snapped",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_by"]
- ]
- },
- {
- "name": "godot_vector2_aspect",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_with"]
- ]
- },
- {
- "name": "godot_vector2_slide",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_bounce",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_reflect",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_abs",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_clamped",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_length"]
- ]
- },
- {
- "name": "godot_vector2_operator_add",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_substract",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_multiply_vector",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_multiply_scalar",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_divide_vector",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_divide_scalar",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_neg",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_set_x",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "p_self"],
- ["const godot_real", "p_x"]
- ]
- },
- {
- "name": "godot_vector2_set_y",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "p_self"],
- ["const godot_real", "p_y"]
- ]
- },
- {
- "name": "godot_vector2_get_x",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_get_y",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_new",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_z"],
- ["const godot_real", "p_w"]
- ]
- },
- {
- "name": "godot_quat_new_with_axis_angle",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_angle"]
- ]
- },
- {
- "name": "godot_quat_get_x",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_x",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_y",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_y",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_z",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_z",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_w",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_w",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_normalized",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_inverse",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_xform",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_quat_slerp",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_slerpni",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_cubic_slerp",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_quat *", "p_pre_a"],
- ["const godot_quat *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_operator_multiply",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_add",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_substract",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_divide",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_neg",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_new_with_rows",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_x_axis"],
- ["const godot_vector3 *", "p_y_axis"],
- ["const godot_vector3 *", "p_z_axis"]
- ]
- },
- {
- "name": "godot_basis_new_with_axis_and_angle",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_basis_new_with_euler",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_euler"]
- ]
- },
- {
- "name": "godot_basis_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_inverse",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_transposed",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_orthonormalized",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_determinant",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_rotated",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_basis_scaled",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_basis_get_scale",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_get_euler",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_tdotx",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_tdoty",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_tdotz",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_xform",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_basis_xform_inv",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_basis_get_orthogonal_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_new",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"]
- ]
- },
- {
- "name": "godot_basis_new_with_euler_quat",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_quat *", "p_euler"]
- ]
- },
- {
- "name": "godot_basis_get_elements",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["godot_vector3 *", "p_elements"]
- ]
- },
- {
- "name": "godot_basis_get_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_int", "p_axis"]
- ]
- },
- {
- "name": "godot_basis_set_axis",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_int", "p_axis"],
- ["const godot_vector3 *", "p_value"]
- ]
- },
- {
- "name": "godot_basis_get_row",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_int", "p_row"]
- ]
- },
- {
- "name": "godot_basis_set_row",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_int", "p_row"],
- ["const godot_vector3 *", "p_value"]
- ]
- },
- {
- "name": "godot_basis_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_add",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_substract",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_multiply_vector",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_multiply_scalar",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector3 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_z"]
- ]
- },
- {
- "name": "godot_vector3_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_min_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_max_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_normalized",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_inverse",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_snapped",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_by"]
- ]
- },
- {
- "name": "godot_vector3_rotated",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_vector3_linear_interpolate",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector3_cubic_interpolate",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"],
- ["const godot_vector3 *", "p_pre_a"],
- ["const godot_vector3 *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector3_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_cross",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_outer",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_to_diagonal_matrix",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_abs",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_floor",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_ceil",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_distance_squared_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_angle_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector3_slide",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_bounce",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_reflect",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_operator_add",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_substract",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_multiply_vector",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_multiply_scalar",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_divide_vector",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_divide_scalar",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_neg",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_set_axis",
- "return_type": "void",
- "arguments": [
- ["godot_vector3 *", "p_self"],
- ["const godot_vector3_axis", "p_axis"],
- ["const godot_real", "p_val"]
- ]
- },
- {
- "name": "godot_vector3_get_axis",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3_axis", "p_axis"]
- ]
- },
- {
- "name": "godot_pool_byte_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_byte_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "r_dest"],
- ["const godot_pool_byte_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_byte_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_byte_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_pool_byte_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_pool_byte_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_byte_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_pool_byte_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_byte_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_pool_byte_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_byte_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_byte_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_pool_byte_array_get",
- "return_type": "uint8_t",
- "arguments": [
- ["const godot_pool_byte_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_byte_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_byte_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_int_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_int_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "r_dest"],
- ["const godot_pool_int_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_int_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_int_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_data"]
- ]
- },
- {
- "name": "godot_pool_int_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_pool_int_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_int_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_int", "p_data"]
- ]
- },
- {
- "name": "godot_pool_int_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_int_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_data"]
- ]
- },
- {
- "name": "godot_pool_int_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_int_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_int_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_int", "p_data"]
- ]
- },
- {
- "name": "godot_pool_int_array_get",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_int_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_int_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_int_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_int_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_real_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_real_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "r_dest"],
- ["const godot_pool_real_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_real_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_real_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_real", "p_data"]
- ]
- },
- {
- "name": "godot_pool_real_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_pool_real_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_real_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_real", "p_data"]
- ]
- },
- {
- "name": "godot_pool_real_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_real_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_real", "p_data"]
- ]
- },
- {
- "name": "godot_pool_real_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_real_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_real_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_real", "p_data"]
- ]
- },
- {
- "name": "godot_pool_real_array_get",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_pool_real_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_real_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_real_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_real_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_string_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_string_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "r_dest"],
- ["const godot_pool_string_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_string_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_string_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_string_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_pool_string_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_string_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_string_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_string_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_string_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_string_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_string_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_string_array_get",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_pool_string_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_string_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_string_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_pool_vector2_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_get",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_pool_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_pool_vector3_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_get",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_pool_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_pool_color_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "r_dest"],
- ["const godot_pool_color_array *", "p_src"]
- ]
- },
- {
- "name": "godot_pool_color_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_pool_color_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_color_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_pool_color_array *", "p_array"]
- ]
- },
- {
- "name": "godot_pool_color_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_color_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_color_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_color_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_pool_color_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_pool_color_array_get",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_pool_color_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_pool_color_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_array *", "p_src"]
- ]
- },
- {
- "name": "godot_array_new_pool_color_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_color_array *", "p_pca"]
- ]
- },
- {
- "name": "godot_array_new_pool_vector3_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_pv3a"]
- ]
- },
- {
- "name": "godot_array_new_pool_vector2_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_pv2a"]
- ]
- },
- {
- "name": "godot_array_new_pool_string_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_string_array *", "p_psa"]
- ]
- },
- {
- "name": "godot_array_new_pool_real_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_real_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_array_new_pool_int_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_int_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_array_new_pool_byte_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_pool_byte_array *", "p_pba"]
- ]
- },
- {
- "name": "godot_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_get",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_operator_index",
- "return_type": "godot_variant *",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_clear",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_erase",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_front",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_back",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_find",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"],
- ["const godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_array_find_last",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"]
- ]
- },
- {
- "name": "godot_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_hash",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_insert",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_pos"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_pop_back",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_pop_front",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_push_front",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_array_rfind",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"],
- ["const godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_sort_custom",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["godot_object *", "p_obj"],
- ["const godot_string *", "p_func"]
- ]
- },
- {
- "name": "godot_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_new",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "r_dest"]
- ]
- },
- {
- "name": "godot_dictionary_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "r_dest"],
- ["const godot_dictionary *", "p_src"]
- ]
- },
- {
- "name": "godot_dictionary_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_clear",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_has",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_has_all",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_array *", "p_keys"]
- ]
- },
- {
- "name": "godot_dictionary_erase",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_hash",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_keys",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_values",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_get",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_set",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_dictionary_operator_index",
- "return_type": "godot_variant *",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_next",
- "return_type": "godot_variant *",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_dictionary *", "p_b"]
- ]
- },
- {
- "name": "godot_dictionary_to_json",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_new",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "r_dest"],
- ["const godot_string *", "p_from"]
- ]
- },
- {
- "name": "godot_node_path_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "r_dest"],
- ["const godot_node_path *", "p_src"]
- ]
- },
- {
- "name": "godot_node_path_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_is_absolute",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_name_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_name",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_node_path_get_subname_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_subname",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_node_path_get_property",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_is_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_node_path *", "p_b"]
- ]
- },
- {
- "name": "godot_plane_new_with_reals",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_real", "p_a"],
- ["const godot_real", "p_b"],
- ["const godot_real", "p_c"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_plane_new_with_vectors",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_vector3 *", "p_v1"],
- ["const godot_vector3 *", "p_v2"],
- ["const godot_vector3 *", "p_v3"]
- ]
- },
- {
- "name": "godot_plane_new_with_normal",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_vector3 *", "p_normal"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_plane_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_normalized",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_center",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_get_any_point",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_is_point_over",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"],
- ["const godot_real", "p_epsilon"]
- ]
- },
- {
- "name": "godot_plane_project",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_intersect_3",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_plane *", "p_b"],
- ["const godot_plane *", "p_c"]
- ]
- },
- {
- "name": "godot_plane_intersects_ray",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_vector3 *", "p_from"],
- ["const godot_vector3 *", "p_dir"]
- ]
- },
- {
- "name": "godot_plane_intersects_segment",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_vector3 *", "p_begin"],
- ["const godot_vector3 *", "p_end"]
- ]
- },
- {
- "name": "godot_plane_operator_neg",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_plane *", "p_b"]
- ]
- },
- {
- "name": "godot_plane_set_normal",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_normal"]
- ]
- },
- {
- "name": "godot_plane_get_normal",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_get_d",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_set_d",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "p_self"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_rect2_new_with_position_and_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "r_dest"],
- ["const godot_vector2 *", "p_pos"],
- ["const godot_vector2 *", "p_size"]
- ]
- },
- {
- "name": "godot_rect2_new",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_width"],
- ["const godot_real", "p_height"]
- ]
- },
- {
- "name": "godot_rect2_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_get_area",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_intersects",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_encloses",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_has_no_area",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_clip",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_merge",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_point"]
- ]
- },
- {
- "name": "godot_rect2_grow",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_real", "p_by"]
- ]
- },
- {
- "name": "godot_rect2_expand",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_rect2_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_get_position",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_get_size",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_set_position",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_pos"]
- ]
- },
- {
- "name": "godot_rect2_set_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_size"]
- ]
- },
- {
- "name": "godot_rect3_new",
- "return_type": "void",
- "arguments": [
- ["godot_rect3 *", "r_dest"],
- ["const godot_vector3 *", "p_pos"],
- ["const godot_vector3 *", "p_size"]
- ]
- },
- {
- "name": "godot_rect3_get_position",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_set_position",
- "return_type": "void",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_rect3_get_size",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_set_size",
- "return_type": "void",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_rect3_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_area",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_has_no_area",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_has_no_surface",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_intersects",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_rect3 *", "p_with"]
- ]
- },
- {
- "name": "godot_rect3_encloses",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_rect3 *", "p_with"]
- ]
- },
- {
- "name": "godot_rect3_merge",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_rect3 *", "p_with"]
- ]
- },
- {
- "name": "godot_rect3_intersection",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_rect3 *", "p_with"]
- ]
- },
- {
- "name": "godot_rect3_intersects_plane",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_plane *", "p_plane"]
- ]
- },
- {
- "name": "godot_rect3_intersects_segment",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_from"],
- ["const godot_vector3 *", "p_to"]
- ]
- },
- {
- "name": "godot_rect3_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_rect3_get_support",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_dir"]
- ]
- },
- {
- "name": "godot_rect3_get_longest_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_longest_axis_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_longest_axis_size",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_shortest_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_shortest_axis_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_get_shortest_axis_size",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_rect3 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect3_expand",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_vector3 *", "p_to_point"]
- ]
- },
- {
- "name": "godot_rect3_grow",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_real", "p_by"]
- ]
- },
- {
- "name": "godot_rect3_get_endpoint",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_rect3_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect3 *", "p_self"],
- ["const godot_rect3 *", "p_b"]
- ]
- },
- {
- "name": "godot_rid_new",
- "return_type": "void",
- "arguments": [
- ["godot_rid *", "r_dest"]
- ]
- },
- {
- "name": "godot_rid_get_id",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_rid *", "p_self"]
- ]
- },
- {
- "name": "godot_rid_new_with_resource",
- "return_type": "void",
- "arguments": [
- ["godot_rid *", "r_dest"],
- ["const godot_object *", "p_from"]
- ]
- },
- {
- "name": "godot_rid_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rid *", "p_self"],
- ["const godot_rid *", "p_b"]
- ]
- },
- {
- "name": "godot_rid_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rid *", "p_self"],
- ["const godot_rid *", "p_b"]
- ]
- },
- {
- "name": "godot_transform_new_with_axis_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"],
- ["const godot_vector3 *", "p_x_axis"],
- ["const godot_vector3 *", "p_y_axis"],
- ["const godot_vector3 *", "p_z_axis"],
- ["const godot_vector3 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform_new",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"],
- ["const godot_basis *", "p_basis"],
- ["const godot_vector3 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform_get_basis",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_set_basis",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "p_self"],
- ["godot_basis *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_get_origin",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_set_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "p_self"],
- ["godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_inverse",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_affine_inverse",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_orthonormalized",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_rotated",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_transform_scaled",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_transform_translated",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_ofs"]
- ]
- },
- {
- "name": "godot_transform_looking_at",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_target"],
- ["const godot_vector3 *", "p_up"]
- ]
- },
- {
- "name": "godot_transform_xform_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_plane *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_plane *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_new_identity",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"]
- ]
- },
- {
- "name": "godot_transform_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_transform *", "p_b"]
- ]
- },
- {
- "name": "godot_transform_operator_multiply",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_transform *", "p_b"]
- ]
- },
- {
- "name": "godot_transform_xform_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_rect3",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_rect3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_rect3",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_rect3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_new",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"],
- ["const godot_real", "p_rot"],
- ["const godot_vector2 *", "p_pos"]
- ]
- },
- {
- "name": "godot_transform2d_new_axis_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"],
- ["const godot_vector2 *", "p_x_axis"],
- ["const godot_vector2 *", "p_y_axis"],
- ["const godot_vector2 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform2d_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_inverse",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_affine_inverse",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_rotation",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_origin",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_scale",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_orthonormalized",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_rotated",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_transform2d_scaled",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_scale"]
- ]
- },
- {
- "name": "godot_transform2d_translated",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_offset"]
- ]
- },
- {
- "name": "godot_transform2d_xform_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_xform_inv_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_basis_xform_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_basis_xform_inv_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_interpolate_with",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_m"],
- ["const godot_real", "p_c"]
- ]
- },
- {
- "name": "godot_transform2d_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_b"]
- ]
- },
- {
- "name": "godot_transform2d_operator_multiply",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_b"]
- ]
- },
- {
- "name": "godot_transform2d_new_identity",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"]
- ]
- },
- {
- "name": "godot_transform2d_xform_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_rect2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_xform_inv_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_rect2 *", "p_v"]
- ]
- },
- {
- "name": "godot_variant_get_type",
- "return_type": "godot_variant_type",
- "arguments": [
- ["const godot_variant *", "p_v"]
- ]
- },
- {
- "name": "godot_variant_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_variant *", "p_src"]
- ]
- },
- {
- "name": "godot_variant_new_nil",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"]
- ]
- },
- {
- "name": "godot_variant_new_bool",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "p_v"],
- ["const godot_bool", "p_b"]
- ]
- },
- {
- "name": "godot_variant_new_uint",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const uint64_t", "p_i"]
- ]
- },
- {
- "name": "godot_variant_new_int",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const int64_t", "p_i"]
- ]
- },
- {
- "name": "godot_variant_new_real",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const double", "p_r"]
- ]
- },
- {
- "name": "godot_variant_new_string",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_string *", "p_s"]
- ]
- },
- {
- "name": "godot_variant_new_vector2",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector2 *", "p_v2"]
- ]
- },
- {
- "name": "godot_variant_new_rect2",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rect2 *", "p_rect2"]
- ]
- },
- {
- "name": "godot_variant_new_vector3",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector3 *", "p_v3"]
- ]
- },
- {
- "name": "godot_variant_new_transform2d",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_transform2d *", "p_t2d"]
- ]
- },
- {
- "name": "godot_variant_new_plane",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_plane *", "p_plane"]
- ]
- },
- {
- "name": "godot_variant_new_quat",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_quat *", "p_quat"]
- ]
- },
- {
- "name": "godot_variant_new_rect3",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rect3 *", "p_rect3"]
- ]
- },
- {
- "name": "godot_variant_new_basis",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_basis *", "p_basis"]
- ]
- },
- {
- "name": "godot_variant_new_transform",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_transform *", "p_trans"]
- ]
- },
- {
- "name": "godot_variant_new_color",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_color *", "p_color"]
- ]
- },
- {
- "name": "godot_variant_new_node_path",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_node_path *", "p_np"]
- ]
- },
- {
- "name": "godot_variant_new_rid",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rid *", "p_rid"]
- ]
- },
- {
- "name": "godot_variant_new_object",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_object *", "p_obj"]
- ]
- },
- {
- "name": "godot_variant_new_dictionary",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_dictionary *", "p_dict"]
- ]
- },
- {
- "name": "godot_variant_new_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_array *", "p_arr"]
- ]
- },
- {
- "name": "godot_variant_new_pool_byte_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_byte_array *", "p_pba"]
- ]
- },
- {
- "name": "godot_variant_new_pool_int_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_int_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_variant_new_pool_real_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_real_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_variant_new_pool_string_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_string_array *", "p_psa"]
- ]
- },
- {
- "name": "godot_variant_new_pool_vector2_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_pv2a"]
- ]
- },
- {
- "name": "godot_variant_new_pool_vector3_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_pv3a"]
- ]
- },
- {
- "name": "godot_variant_new_pool_color_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_pool_color_array *", "p_pca"]
- ]
- },
- {
- "name": "godot_variant_as_bool",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_uint",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_int",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_real",
- "return_type": "double",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_transform2d",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_quat",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rect3",
- "return_type": "godot_rect3",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_basis",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_transform",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_color",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_node_path",
- "return_type": "godot_node_path",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rid",
- "return_type": "godot_rid",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_object",
- "return_type": "godot_object *",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_dictionary",
- "return_type": "godot_dictionary",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_array",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_byte_array",
- "return_type": "godot_pool_byte_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_int_array",
- "return_type": "godot_pool_int_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_real_array",
- "return_type": "godot_pool_real_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_string_array",
- "return_type": "godot_pool_string_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_vector2_array",
- "return_type": "godot_pool_vector2_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_vector3_array",
- "return_type": "godot_pool_vector3_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_pool_color_array",
- "return_type": "godot_pool_color_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_call",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_variant *", "p_self"],
- ["const godot_string *", "p_method"],
- ["const godot_variant **", "p_args"],
- ["const godot_int", "p_argcount"],
- ["godot_variant_call_error *", "r_error"]
- ]
- },
- {
- "name": "godot_variant_has_method",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_string *", "p_method"]
- ]
- },
- {
- "name": "godot_variant_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_hash_compare",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_booleanize",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_string_new",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"]
- ]
- },
- {
- "name": "godot_string_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const godot_string *", "p_src"]
- ]
- },
- {
- "name": "godot_string_new_data",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_new_unicode_data",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const wchar_t *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_get_data",
- "return_type": "void",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["char *", "p_dest"],
- ["int *", "p_size"]
- ]
- },
- {
- "name": "godot_string_operator_index",
- "return_type": "wchar_t *",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_string_c_str",
- "return_type": "const char *",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_unicode_str",
- "return_type": "const wchar_t *",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_operator_plus",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_length",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_begins_with",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_begins_with_char_array",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const char *", "p_char_array"]
- ]
- },
- {
- "name": "godot_string_bigrams",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_chr",
- "return_type": "godot_string",
- "arguments": [
- ["wchar_t", "p_character"]
- ]
- },
- {
- "name": "godot_string_ends_with",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_find",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
- "name": "godot_string_find_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_findmk",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"]
- ]
- },
- {
- "name": "godot_string_findmk_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_findmk_from_in_place",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"],
- ["godot_int", "p_from"],
- ["godot_int *", "r_key"]
- ]
- },
- {
- "name": "godot_string_findn",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
- "name": "godot_string_findn_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_find_last",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
- "name": "godot_string_format",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_variant *", "p_values"]
- ]
- },
- {
- "name": "godot_string_format_with_custom_placeholder",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_variant *", "p_values"],
- ["const char *", "p_placeholder"]
- ]
- },
- {
- "name": "godot_string_hex_encode_buffer",
- "return_type": "godot_string",
- "arguments": [
- ["const uint8_t *", "p_buffer"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hex_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hex_to_int_without_prefix",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_insert",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_at_pos"],
- ["godot_string", "p_string"]
- ]
- },
- {
- "name": "godot_string_is_numeric",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_subsequence_of",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_is_subsequence_ofi",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_lpad",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"]
- ]
- },
- {
- "name": "godot_string_lpad_with_custom_character",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"],
- ["const godot_string *", "p_character"]
- ]
- },
- {
- "name": "godot_string_match",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_wildcard"]
- ]
- },
- {
- "name": "godot_string_matchn",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_wildcard"]
- ]
- },
- {
- "name": "godot_string_md5",
- "return_type": "godot_string",
- "arguments": [
- ["const uint8_t *", "p_md5"]
- ]
- },
- {
- "name": "godot_string_num",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_int64",
- "return_type": "godot_string",
- "arguments": [
- ["int64_t", "p_num"],
- ["godot_int", "p_base"]
- ]
- },
- {
- "name": "godot_string_num_int64_capitalized",
- "return_type": "godot_string",
- "arguments": [
- ["int64_t", "p_num"],
- ["godot_int", "p_base"],
- ["godot_bool", "p_capitalize_hex"]
- ]
- },
- {
- "name": "godot_string_num_real",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_scientific",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_with_decimals",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"],
- ["godot_int", "p_decimals"]
- ]
- },
- {
- "name": "godot_string_pad_decimals",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_digits"]
- ]
- },
- {
- "name": "godot_string_pad_zeros",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_digits"]
- ]
- },
- {
- "name": "godot_string_replace_first",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
- ]
- },
- {
- "name": "godot_string_replace",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
- ]
- },
- {
- "name": "godot_string_replacen",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
- ]
- },
- {
- "name": "godot_string_rfind",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
- "name": "godot_string_rfindn",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
- ]
- },
- {
- "name": "godot_string_rfind_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_rfindn_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_rpad",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"]
- ]
- },
- {
- "name": "godot_string_rpad_with_custom_character",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"],
- ["const godot_string *", "p_character"]
- ]
- },
- {
- "name": "godot_string_similarity",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_sprintf",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_values"],
- ["godot_bool *", "p_error"]
- ]
- },
- {
- "name": "godot_string_substr",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_from"],
- ["godot_int", "p_chars"]
- ]
- },
- {
- "name": "godot_string_to_double",
- "return_type": "double",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_float",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_camelcase_to_underscore",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_camelcase_to_underscore_lowercased",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_capitalize",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_char_to_double",
- "return_type": "double",
- "arguments": [
- ["const char *", "p_what"]
- ]
- },
- {
- "name": "godot_string_char_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const char *", "p_what"]
- ]
- },
- {
- "name": "godot_string_wchar_to_int",
- "return_type": "int64_t",
- "arguments": [
- ["const wchar_t *", "p_str"]
- ]
- },
- {
- "name": "godot_string_char_to_int_with_len",
- "return_type": "godot_int",
- "arguments": [
- ["const char *", "p_what"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_char_to_int64_with_len",
- "return_type": "int64_t",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hex_to_int64",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hex_to_int64_with_prefix",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_int64",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_unicode_char_to_double",
- "return_type": "double",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["const wchar_t **", "r_end"]
- ]
- },
- {
- "name": "godot_string_get_slice_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_get_slice",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_string", "p_splitter"],
- ["godot_int", "p_slice"]
- ]
- },
- {
- "name": "godot_string_get_slicec",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["wchar_t", "p_splitter"],
- ["godot_int", "p_slice"]
- ]
- },
- {
- "name": "godot_string_split",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_allow_empty",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_floats",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_floats_allows_empty",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_floats_mk",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_floats_mk_allows_empty",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_ints",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_ints_allows_empty",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_ints_mk",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_ints_mk_allows_empty",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_spaces",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_char_lowercase",
- "return_type": "wchar_t",
- "arguments": [
- ["wchar_t", "p_char"]
- ]
- },
- {
- "name": "godot_string_char_uppercase",
- "return_type": "wchar_t",
- "arguments": [
- ["wchar_t", "p_char"]
- ]
- },
- {
- "name": "godot_string_to_lower",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_upper",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_basename",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_extension",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_left",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_pos"]
- ]
- },
- {
- "name": "godot_string_ord_at",
- "return_type": "wchar_t",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_string_plus_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_file"]
- ]
- },
- {
- "name": "godot_string_right",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_pos"]
- ]
- },
- {
- "name": "godot_string_strip_edges",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_bool", "p_left"],
- ["godot_bool", "p_right"]
- ]
- },
- {
- "name": "godot_string_strip_escapes",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_erase",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"],
- ["godot_int", "p_pos"],
- ["godot_int", "p_chars"]
- ]
- },
- {
- "name": "godot_string_ascii",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"],
- ["char *", "result"]
- ]
- },
- {
- "name": "godot_string_ascii_extended",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"],
- ["char *", "result"]
- ]
- },
- {
- "name": "godot_string_utf8",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"],
- ["char *", "result"]
- ]
- },
- {
- "name": "godot_string_parse_utf8",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char *", "p_utf8"]
- ]
- },
- {
- "name": "godot_string_parse_utf8_with_len",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char *", "p_utf8"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_chars_to_utf8",
- "return_type": "godot_string",
- "arguments": [
- ["const char *", "p_utf8"]
- ]
- },
- {
- "name": "godot_string_chars_to_utf8_with_len",
- "return_type": "godot_string",
- "arguments": [
- ["const char *", "p_utf8"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hash64",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hash_chars",
- "return_type": "uint32_t",
- "arguments": [
- ["const char *", "p_cstr"]
- ]
- },
- {
- "name": "godot_string_hash_chars_with_len",
- "return_type": "uint32_t",
- "arguments": [
- ["const char *", "p_cstr"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hash_utf8_chars",
- "return_type": "uint32_t",
- "arguments": [
- ["const wchar_t *", "p_str"]
- ]
- },
- {
- "name": "godot_string_hash_utf8_chars_with_len",
- "return_type": "uint32_t",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_md5_buffer",
- "return_type": "godot_pool_byte_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_md5_text",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha256_buffer",
- "return_type": "godot_pool_byte_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha256_text",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_base_dir",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_humanize_size",
- "return_type": "godot_string",
- "arguments": [
- ["size_t", "p_size"]
- ]
- },
- {
- "name": "godot_string_is_abs_path",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_rel_path",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_resource_file",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_path_to",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_path"]
- ]
- },
- {
- "name": "godot_string_path_to_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_path"]
- ]
- },
- {
- "name": "godot_string_simplify_path",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_escape_multiline",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_http_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_http_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_json_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_word_wrap",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_chars_per_line"]
- ]
- },
- {
- "name": "godot_string_xml_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_xml_escape_with_quotes",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_xml_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_percent_decode",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_percent_encode",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_float",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_hex_number",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_bool", "p_with_prefix"]
- ]
- },
- {
- "name": "godot_string_is_valid_html_color",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_identifier",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_integer",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_ip_address",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_new",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "r_dest"],
- ["const godot_string *", "p_name"]
- ]
- },
- {
- "name": "godot_string_name_new_data",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "r_dest"],
- ["const char *", "p_name"]
- ]
- },
- {
- "name": "godot_string_name_get_name",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_get_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_get_data_unique_pointer",
- "return_type": "const void *",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string_name *", "p_self"],
- ["const godot_string_name *", "p_other"]
- ]
- },
- {
- "name": "godot_string_name_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string_name *", "p_self"],
- ["const godot_string_name *", "p_other"]
- ]
- },
- {
- "name": "godot_string_name_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_object_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_o"]
- ]
- },
- {
- "name": "godot_global_get_singleton",
- "return_type": "godot_object *",
- "arguments": [
- ["char *", "p_name"]
- ]
- },
- {
- "name": "godot_method_bind_get_method",
- "return_type": "godot_method_bind *",
- "arguments": [
- ["const char *", "p_classname"],
- ["const char *", "p_methodname"]
- ]
- },
- {
- "name": "godot_method_bind_ptrcall",
- "return_type": "void",
- "arguments": [
- ["godot_method_bind *", "p_method_bind"],
- ["godot_object *", "p_instance"],
- ["const void **", "p_args"],
- ["void *", "p_ret"]
- ]
- },
- {
- "name": "godot_method_bind_call",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_method_bind *", "p_method_bind"],
- ["godot_object *", "p_instance"],
- ["const godot_variant **", "p_args"],
- ["const int", "p_arg_count"],
- ["godot_variant_call_error *", "p_call_error"]
- ]
- },
- {
- "name": "godot_get_class_constructor",
- "return_type": "godot_class_constructor",
- "arguments": [
- ["const char *", "p_classname"]
- ]
- },
- {
- "name": "godot_alloc",
- "return_type": "void *",
- "arguments": [
- ["int", "p_bytes"]
- ]
- },
- {
- "name": "godot_realloc",
- "return_type": "void *",
- "arguments": [
- ["void *", "p_ptr"],
- ["int", "p_bytes"]
- ]
- },
- {
- "name": "godot_free",
- "return_type": "void",
- "arguments": [
- ["void *", "p_ptr"]
- ]
- },
- {
- "name": "godot_print_error",
- "return_type": "void",
- "arguments": [
- ["const char *", "p_description"],
- ["const char *", "p_function"],
- ["const char *", "p_file"],
- ["int", "p_line"]
- ]
- },
- {
- "name": "godot_print_warning",
- "return_type": "void",
- "arguments": [
- ["const char *", "p_description"],
- ["const char *", "p_function"],
- ["const char *", "p_file"],
- ["int", "p_line"]
- ]
- },
- {
- "name": "godot_print",
- "return_type": "void",
- "arguments": [
- ["const godot_string *", "p_message"]
- ]
- },
- {
- "name": "godot_nativescript_register_class",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_base"],
- ["godot_instance_create_func", "p_create_func"],
- ["godot_instance_destroy_func", "p_destroy_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_tool_class",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_base"],
- ["godot_instance_create_func", "p_create_func"],
- ["godot_instance_destroy_func", "p_destroy_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_method",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_function_name"],
- ["godot_method_attributes", "p_attr"],
- ["godot_instance_method", "p_method"]
- ]
- },
- {
- "name": "godot_nativescript_register_property",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_path"],
- ["godot_property_attributes *", "p_attr"],
- ["godot_property_set_func", "p_set_func"],
- ["godot_property_get_func", "p_get_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_signal",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const godot_signal *", "p_signal"]
- ]
- },
- {
- "name": "godot_nativescript_get_userdata",
- "return_type": "void *",
- "arguments": [
- ["godot_object *", "p_instance"]
- ]
- },
- {
- "name": "godot_arvr_get_worldscale",
- "return_type": "godot_real",
- "arguments": []
- },
- {
- "name": "godot_arvr_get_reference_frame",
- "return_type": "godot_transform",
- "arguments": []
- },
- {
- "name": "godot_arvr_blit",
- "return_type": "void",
- "arguments": [
- ["int", "p_eye"],
- ["godot_rid *", "p_render_target"],
- ["godot_rect2 *", "p_screen_rect"]
- ]
- },
- {
- "name": "godot_arvr_get_texid",
- "return_type": "godot_int",
- "arguments": [
- ["godot_rid *", "p_render_target"]
- ]
- },
- {
- "name": "godot_arvr_add_controller",
- "return_type": "godot_int",
- "arguments": [
- ["char *", "p_device_name"],
- ["godot_int", "p_hand"],
- ["godot_bool", "p_tracks_orientation"],
- ["godot_bool", "p_tracks_position"]
- ]
- },
- {
- "name": "godot_arvr_remove_controller",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"]
- ]
- },
- {
- "name": "godot_arvr_set_controller_transform",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_transform *", "p_transform"],
- ["godot_bool", "p_tracks_orientation"],
- ["godot_bool", "p_tracks_position"]
- ]
- },
- {
- "name": "godot_arvr_set_controller_button",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_int", "p_button"],
- ["godot_bool", "p_is_pressed"]
- ]
- },
- {
- "name": "godot_arvr_set_controller_axis",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_int", "p_exis"],
- ["godot_real", "p_value"],
- ["godot_bool", "p_can_be_negative"]
+ "core": {
+ "type": "CORE",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "api": [
+ {
+ "name": "godot_color_new_rgba",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "r_dest"],
+ ["const godot_real", "p_r"],
+ ["const godot_real", "p_g"],
+ ["const godot_real", "p_b"],
+ ["const godot_real", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_color_new_rgb",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "r_dest"],
+ ["const godot_real", "p_r"],
+ ["const godot_real", "p_g"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_color_get_r",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_set_r",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "p_self"],
+ ["const godot_real", "r"]
+ ]
+ },
+ {
+ "name": "godot_color_get_g",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_set_g",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "p_self"],
+ ["const godot_real", "g"]
+ ]
+ },
+ {
+ "name": "godot_color_get_b",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_set_b",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "p_self"],
+ ["const godot_real", "b"]
+ ]
+ },
+ {
+ "name": "godot_color_get_a",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_set_a",
+ "return_type": "void",
+ "arguments": [
+ ["godot_color *", "p_self"],
+ ["const godot_real", "a"]
+ ]
+ },
+ {
+ "name": "godot_color_get_h",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_get_s",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_get_v",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_to_rgba32",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_to_argb32",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_gray",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_inverted",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_contrasted",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_linear_interpolate",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_color *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_color_blend",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_color *", "p_over"]
+ ]
+ },
+ {
+ "name": "godot_color_to_html",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_bool", "p_with_alpha"]
+ ]
+ },
+ {
+ "name": "godot_color_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_color *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_color_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_color *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2 *", "r_dest"],
+ ["const godot_real", "p_x"],
+ ["const godot_real", "p_y"]
+ ]
+ },
+ {
+ "name": "godot_vector2_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_normalized",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_length",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_angle",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_length_squared",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_is_normalized",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_distance_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_distance_squared_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_angle_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_angle_to_point",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_linear_interpolate",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_vector2_cubic_interpolate",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"],
+ ["const godot_vector2 *", "p_pre_a"],
+ ["const godot_vector2 *", "p_post_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_vector2_rotated",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_vector2_tangent",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_floor",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_snapped",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_vector2_aspect",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_dot",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_vector2_slide",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector2_bounce",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector2_reflect",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector2_abs",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_clamped",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_real", "p_length"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_add",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_substract",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_multiply_vector",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_multiply_scalar",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_divide_vector",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_divide_scalar",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_neg",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_set_x",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2 *", "p_self"],
+ ["const godot_real", "p_x"]
+ ]
+ },
+ {
+ "name": "godot_vector2_set_y",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2 *", "p_self"],
+ ["const godot_real", "p_y"]
+ ]
+ },
+ {
+ "name": "godot_vector2_get_x",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_get_y",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "r_dest"],
+ ["const godot_real", "p_x"],
+ ["const godot_real", "p_y"],
+ ["const godot_real", "p_z"],
+ ["const godot_real", "p_w"]
+ ]
+ },
+ {
+ "name": "godot_quat_new_with_axis_angle",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "r_dest"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_angle"]
+ ]
+ },
+ {
+ "name": "godot_quat_get_x",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_set_x",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "p_self"],
+ ["const godot_real", "val"]
+ ]
+ },
+ {
+ "name": "godot_quat_get_y",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_set_y",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "p_self"],
+ ["const godot_real", "val"]
+ ]
+ },
+ {
+ "name": "godot_quat_get_z",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_set_z",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "p_self"],
+ ["const godot_real", "val"]
+ ]
+ },
+ {
+ "name": "godot_quat_get_w",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_set_w",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "p_self"],
+ ["const godot_real", "val"]
+ ]
+ },
+ {
+ "name": "godot_quat_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_length",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_length_squared",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_normalized",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_is_normalized",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_inverse",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_dot",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_xform",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_quat_slerp",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_quat_slerpni",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_quat_cubic_slerp",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"],
+ ["const godot_quat *", "p_pre_a"],
+ ["const godot_quat *", "p_post_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_multiply",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_add",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_substract",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_divide",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_quat *", "p_self"],
+ ["const godot_quat *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_neg",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_quat *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_new_with_rows",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "r_dest"],
+ ["const godot_vector3 *", "p_x_axis"],
+ ["const godot_vector3 *", "p_y_axis"],
+ ["const godot_vector3 *", "p_z_axis"]
+ ]
+ },
+ {
+ "name": "godot_basis_new_with_axis_and_angle",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "r_dest"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_basis_new_with_euler",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "r_dest"],
+ ["const godot_vector3 *", "p_euler"]
+ ]
+ },
+ {
+ "name": "godot_basis_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_inverse",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_transposed",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_orthonormalized",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_determinant",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_rotated",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_basis_scaled",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_scale",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_euler",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_tdotx",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_basis_tdoty",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_basis_tdotz",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_basis_xform",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_basis_xform_inv",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_orthogonal_index",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_basis_new_with_euler_quat",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "r_dest"],
+ ["const godot_quat *", "p_euler"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_elements",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["godot_vector3 *", "p_elements"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_axis",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_int", "p_axis"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_axis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_int", "p_axis"],
+ ["const godot_vector3 *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_basis_get_row",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_int", "p_row"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_row",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_int", "p_row"],
+ ["const godot_vector3 *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_basis *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_add",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_basis *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_substract",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_basis *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_multiply_vector",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_basis *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_multiply_scalar",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector3 *", "r_dest"],
+ ["const godot_real", "p_x"],
+ ["const godot_real", "p_y"],
+ ["const godot_real", "p_z"]
+ ]
+ },
+ {
+ "name": "godot_vector3_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_min_axis",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_max_axis",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_length",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_length_squared",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_is_normalized",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_normalized",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_inverse",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_snapped",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_vector3_rotated",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_vector3_linear_interpolate",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_vector3_cubic_interpolate",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"],
+ ["const godot_vector3 *", "p_pre_a"],
+ ["const godot_vector3 *", "p_post_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_vector3_dot",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_cross",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_outer",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_to_diagonal_matrix",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_abs",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_floor",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_ceil",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_distance_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_distance_squared_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_angle_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector3_slide",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector3_bounce",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector3_reflect",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_n"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_add",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_substract",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_multiply_vector",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_multiply_scalar",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_divide_vector",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_divide_scalar",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_real", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_neg",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_set_axis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector3 *", "p_self"],
+ ["const godot_vector3_axis", "p_axis"],
+ ["const godot_real", "p_val"]
+ ]
+ },
+ {
+ "name": "godot_vector3_get_axis",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3_axis", "p_axis"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "r_dest"],
+ ["const godot_pool_byte_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const uint8_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const godot_pool_byte_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const uint8_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const uint8_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_read",
+ "return_type": "godot_pool_byte_array_read_access *",
+ "arguments": [
+ ["const godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_write",
+ "return_type": "godot_pool_byte_array_write_access *",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const uint8_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_get",
+ "return_type": "uint8_t",
+ "arguments": [
+ ["const godot_pool_byte_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "r_dest"],
+ ["const godot_pool_int_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_pool_int_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_int", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_read",
+ "return_type": "godot_pool_int_array_read_access *",
+ "arguments": [
+ ["const godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_write",
+ "return_type": "godot_pool_int_array_write_access *",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_int", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_get",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_int_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "r_dest"],
+ ["const godot_pool_real_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_real", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_pool_real_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_real", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_real", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_read",
+ "return_type": "godot_pool_real_array_read_access *",
+ "arguments": [
+ ["const godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_write",
+ "return_type": "godot_pool_real_array_write_access *",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_real", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_get",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_pool_real_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "r_dest"],
+ ["const godot_pool_string_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_string *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_pool_string_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_string *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_string *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_read",
+ "return_type": "godot_pool_string_array_read_access *",
+ "arguments": [
+ ["const godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_write",
+ "return_type": "godot_pool_string_array_write_access *",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_string *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_get",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_pool_string_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "r_dest"],
+ ["const godot_pool_vector2_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_vector2 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_pool_vector2_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_vector2 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_vector2 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_read",
+ "return_type": "godot_pool_vector2_array_read_access *",
+ "arguments": [
+ ["const godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_write",
+ "return_type": "godot_pool_vector2_array_write_access *",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_vector2 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_get",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_pool_vector2_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "r_dest"],
+ ["const godot_pool_vector3_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_vector3 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_pool_vector3_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_vector3 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_vector3 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_read",
+ "return_type": "godot_pool_vector3_array_read_access *",
+ "arguments": [
+ ["const godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_write",
+ "return_type": "godot_pool_vector3_array_write_access *",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_vector3 *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_get",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_pool_vector3_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "r_dest"],
+ ["const godot_pool_color_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_color *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_pool_color_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_color *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_color *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_read",
+ "return_type": "godot_pool_color_array_read_access *",
+ "arguments": [
+ ["const godot_pool_color_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_write",
+ "return_type": "godot_pool_color_array_write_access *",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_color *", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_get",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_pool_color_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_pool_color_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_read_access_ptr",
+ "return_type": "const uint8_t *",
+ "arguments": [
+ ["const godot_pool_byte_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array_read_access *", "p_read"],
+ ["godot_pool_byte_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_read_access_ptr",
+ "return_type": "const godot_int *",
+ "arguments": [
+ ["const godot_pool_int_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array_read_access *", "p_read"],
+ ["godot_pool_int_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_read_access_ptr",
+ "return_type": "const godot_real *",
+ "arguments": [
+ ["const godot_pool_real_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array_read_access *", "p_read"],
+ ["godot_pool_real_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_read_access_ptr",
+ "return_type": "const godot_string *",
+ "arguments": [
+ ["const godot_pool_string_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array_read_access *", "p_read"],
+ ["godot_pool_string_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_read_access_ptr",
+ "return_type": "const godot_vector2 *",
+ "arguments": [
+ ["const godot_pool_vector2_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array_read_access *", "p_read"],
+ ["godot_pool_vector2_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_read_access_ptr",
+ "return_type": "const godot_vector3 *",
+ "arguments": [
+ ["const godot_pool_vector3_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array_read_access *", "p_read"],
+ ["godot_pool_vector3_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_read_access_ptr",
+ "return_type": "const godot_color *",
+ "arguments": [
+ ["const godot_pool_color_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_read_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array_read_access *", "p_read"],
+ ["godot_pool_color_array_read_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_read_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array_read_access *", "p_read"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_write_access_ptr",
+ "return_type": "uint8_t *",
+ "arguments": [
+ ["const godot_pool_byte_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array_write_access *", "p_write"],
+ ["godot_pool_byte_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_byte_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_byte_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_write_access_ptr",
+ "return_type": "godot_int *",
+ "arguments": [
+ ["const godot_pool_int_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array_write_access *", "p_write"],
+ ["godot_pool_int_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_int_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_write_access_ptr",
+ "return_type": "godot_real *",
+ "arguments": [
+ ["const godot_pool_real_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array_write_access *", "p_write"],
+ ["godot_pool_real_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_real_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_write_access_ptr",
+ "return_type": "godot_string *",
+ "arguments": [
+ ["const godot_pool_string_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array_write_access *", "p_write"],
+ ["godot_pool_string_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_string_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_write_access_ptr",
+ "return_type": "godot_vector2 *",
+ "arguments": [
+ ["const godot_pool_vector2_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array_write_access *", "p_write"],
+ ["godot_pool_vector2_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector2_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_write_access_ptr",
+ "return_type": "godot_vector3 *",
+ "arguments": [
+ ["const godot_pool_vector3_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array_write_access *", "p_write"],
+ ["godot_pool_vector3_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_vector3_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_write_access_ptr",
+ "return_type": "godot_color *",
+ "arguments": [
+ ["const godot_pool_color_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_write_access_operator_assign",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array_write_access *", "p_write"],
+ ["godot_pool_color_array_write_access *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_write_access_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_pool_color_array_write_access *", "p_write"]
+ ]
+ },
+ {
+ "name": "godot_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_color_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_color_array *", "p_pca"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_vector3_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_vector3_array *", "p_pv3a"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_vector2_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_vector2_array *", "p_pv2a"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_string_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_string_array *", "p_psa"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_real_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_real_array *", "p_pra"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_int_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_int_array *", "p_pia"]
+ ]
+ },
+ {
+ "name": "godot_array_new_pool_byte_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_pool_byte_array *", "p_pba"]
+ ]
+ },
+ {
+ "name": "godot_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_get",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_array_operator_index",
+ "return_type": "godot_variant *",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_array_operator_index_const",
+ "return_type": "const godot_variant *",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_clear",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_erase",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_front",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_back",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_find",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_variant *", "p_what"],
+ ["const godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_array_find_last",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_variant *", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_array_has",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_hash",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_insert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_int", "p_pos"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_pop_back",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_pop_front",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_push_front",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_array_rfind",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_variant *", "p_what"],
+ ["const godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_sort",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_sort_custom",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"],
+ ["godot_object *", "p_obj"],
+ ["const godot_string *", "p_func"]
+ ]
+ },
+ {
+ "name": "godot_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "r_dest"],
+ ["const godot_dictionary *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_clear",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_has",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_has_all",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_array *", "p_keys"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_erase",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_hash",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_keys",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_values",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_get",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"],
+ ["const godot_variant *", "p_value"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_operator_index",
+ "return_type": "godot_variant *",
+ "arguments": [
+ ["godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_operator_index_const",
+ "return_type": "const godot_variant *",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_next",
+ "return_type": "godot_variant *",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"],
+ ["const godot_dictionary *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_to_json",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_dictionary *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_node_path *", "r_dest"],
+ ["const godot_string *", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_node_path_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_node_path *", "r_dest"],
+ ["const godot_node_path *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_node_path_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_is_absolute",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_name_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_name",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_node_path *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_subname_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_subname",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_node_path *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_property",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_is_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_node_path_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_node_path *", "p_self"],
+ ["const godot_node_path *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_plane_new_with_reals",
+ "return_type": "void",
+ "arguments": [
+ ["godot_plane *", "r_dest"],
+ ["const godot_real", "p_a"],
+ ["const godot_real", "p_b"],
+ ["const godot_real", "p_c"],
+ ["const godot_real", "p_d"]
+ ]
+ },
+ {
+ "name": "godot_plane_new_with_vectors",
+ "return_type": "void",
+ "arguments": [
+ ["godot_plane *", "r_dest"],
+ ["const godot_vector3 *", "p_v1"],
+ ["const godot_vector3 *", "p_v2"],
+ ["const godot_vector3 *", "p_v3"]
+ ]
+ },
+ {
+ "name": "godot_plane_new_with_normal",
+ "return_type": "void",
+ "arguments": [
+ ["godot_plane *", "r_dest"],
+ ["const godot_vector3 *", "p_normal"],
+ ["const godot_real", "p_d"]
+ ]
+ },
+ {
+ "name": "godot_plane_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_normalized",
+ "return_type": "godot_plane",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_center",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_get_any_point",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_is_point_over",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["const godot_vector3 *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_plane_distance_to",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["const godot_vector3 *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_plane_has_point",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["const godot_vector3 *", "p_point"],
+ ["const godot_real", "p_epsilon"]
+ ]
+ },
+ {
+ "name": "godot_plane_project",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["const godot_vector3 *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_plane_intersect_3",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["godot_vector3 *", "r_dest"],
+ ["const godot_plane *", "p_b"],
+ ["const godot_plane *", "p_c"]
+ ]
+ },
+ {
+ "name": "godot_plane_intersects_ray",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["godot_vector3 *", "r_dest"],
+ ["const godot_vector3 *", "p_from"],
+ ["const godot_vector3 *", "p_dir"]
+ ]
+ },
+ {
+ "name": "godot_plane_intersects_segment",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["godot_vector3 *", "r_dest"],
+ ["const godot_vector3 *", "p_begin"],
+ ["const godot_vector3 *", "p_end"]
+ ]
+ },
+ {
+ "name": "godot_plane_operator_neg",
+ "return_type": "godot_plane",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_plane *", "p_self"],
+ ["const godot_plane *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_plane_set_normal",
+ "return_type": "void",
+ "arguments": [
+ ["godot_plane *", "p_self"],
+ ["const godot_vector3 *", "p_normal"]
+ ]
+ },
+ {
+ "name": "godot_plane_get_normal",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_get_d",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_plane *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_plane_set_d",
+ "return_type": "void",
+ "arguments": [
+ ["godot_plane *", "p_self"],
+ ["const godot_real", "p_d"]
+ ]
+ },
+ {
+ "name": "godot_rect2_new_with_position_and_size",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2 *", "r_dest"],
+ ["const godot_vector2 *", "p_pos"],
+ ["const godot_vector2 *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_rect2_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2 *", "r_dest"],
+ ["const godot_real", "p_x"],
+ ["const godot_real", "p_y"],
+ ["const godot_real", "p_width"],
+ ["const godot_real", "p_height"]
+ ]
+ },
+ {
+ "name": "godot_rect2_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_get_area",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_intersects",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_rect2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2_encloses",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_rect2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2_has_no_area",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_clip",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_rect2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2_merge",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_rect2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2_has_point",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_vector2 *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_rect2_grow",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_real", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_rect2_expand",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_rect2_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_rect2 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2_get_position",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_get_size",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_set_position",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2 *", "p_self"],
+ ["const godot_vector2 *", "p_pos"]
+ ]
+ },
+ {
+ "name": "godot_rect2_set_size",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2 *", "p_self"],
+ ["const godot_vector2 *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_rect3_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect3 *", "r_dest"],
+ ["const godot_vector3 *", "p_pos"],
+ ["const godot_vector3 *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_position",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_set_position",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_size",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_set_size",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_rect3_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_area",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_has_no_area",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_has_no_surface",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_intersects",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_rect3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_rect3_encloses",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_rect3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_rect3_merge",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_rect3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_rect3_intersection",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_rect3 *", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_rect3_intersects_plane",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_plane *", "p_plane"]
+ ]
+ },
+ {
+ "name": "godot_rect3_intersects_segment",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_from"],
+ ["const godot_vector3 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_rect3_has_point",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_support",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_dir"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_longest_axis",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_longest_axis_index",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_longest_axis_size",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_shortest_axis",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_shortest_axis_index",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_shortest_axis_size",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect3_expand",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_vector3 *", "p_to_point"]
+ ]
+ },
+ {
+ "name": "godot_rect3_grow",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_real", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_rect3_get_endpoint",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_rect3_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect3 *", "p_self"],
+ ["const godot_rect3 *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rid_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rid *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_rid_get_id",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_rid *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rid_new_with_resource",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rid *", "r_dest"],
+ ["const godot_object *", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_rid_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rid *", "p_self"],
+ ["const godot_rid *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rid_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rid *", "p_self"],
+ ["const godot_rid *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_transform_new_with_axis_origin",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "r_dest"],
+ ["const godot_vector3 *", "p_x_axis"],
+ ["const godot_vector3 *", "p_y_axis"],
+ ["const godot_vector3 *", "p_z_axis"],
+ ["const godot_vector3 *", "p_origin"]
+ ]
+ },
+ {
+ "name": "godot_transform_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "r_dest"],
+ ["const godot_basis *", "p_basis"],
+ ["const godot_vector3 *", "p_origin"]
+ ]
+ },
+ {
+ "name": "godot_transform_get_basis",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_set_basis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "p_self"],
+ ["godot_basis *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_get_origin",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_set_origin",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "p_self"],
+ ["godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_inverse",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_affine_inverse",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_orthonormalized",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform_rotated",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_transform_scaled",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_transform_translated",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_ofs"]
+ ]
+ },
+ {
+ "name": "godot_transform_looking_at",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_target"],
+ ["const godot_vector3 *", "p_up"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_plane",
+ "return_type": "godot_plane",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_plane *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_inv_plane",
+ "return_type": "godot_plane",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_plane *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_new_identity",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_transform_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_transform *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_transform_operator_multiply",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_transform *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_vector3",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_inv_vector3",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_vector3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_rect3",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_rect3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform_xform_inv_rect3",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_transform *", "p_self"],
+ ["const godot_rect3 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform2d *", "r_dest"],
+ ["const godot_real", "p_rot"],
+ ["const godot_vector2 *", "p_pos"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_new_axis_origin",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform2d *", "r_dest"],
+ ["const godot_vector2 *", "p_x_axis"],
+ ["const godot_vector2 *", "p_y_axis"],
+ ["const godot_vector2 *", "p_origin"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_inverse",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_affine_inverse",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_get_rotation",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_get_origin",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_get_scale",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_orthonormalized",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_rotated",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_real", "p_phi"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_scaled",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_translated",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_offset"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_xform_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_xform_inv_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_basis_xform_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_basis_xform_inv_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_vector2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_interpolate_with",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_transform2d *", "p_m"],
+ ["const godot_real", "p_c"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_transform2d *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_operator_multiply",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_transform2d *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_new_identity",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform2d *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_xform_rect2",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_rect2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_transform2d_xform_inv_rect2",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_transform2d *", "p_self"],
+ ["const godot_rect2 *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_variant_get_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ ["const godot_variant *", "p_v"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_variant *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_nil",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_bool",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "p_v"],
+ ["const godot_bool", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_uint",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const uint64_t", "p_i"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_int",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const int64_t", "p_i"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_real",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const double", "p_r"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_string",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_string *", "p_s"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector2",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_vector2 *", "p_v2"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rect2",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_rect2 *", "p_rect2"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector3",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_vector3 *", "p_v3"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_transform2d",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_transform2d *", "p_t2d"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_plane",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_plane *", "p_plane"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_quat",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_quat *", "p_quat"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rect3",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_rect3 *", "p_rect3"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_basis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_basis *", "p_basis"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_transform",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_transform *", "p_trans"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_color",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_color *", "p_color"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_node_path",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_node_path *", "p_np"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rid",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_rid *", "p_rid"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_object",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_object *", "p_obj"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_dictionary",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_dictionary *", "p_dict"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_array *", "p_arr"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_byte_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_byte_array *", "p_pba"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_int_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_int_array *", "p_pia"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_real_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_real_array *", "p_pra"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_string_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_string_array *", "p_psa"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_vector2_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_vector2_array *", "p_pv2a"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_vector3_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_vector3_array *", "p_pv3a"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_pool_color_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_pool_color_array *", "p_pca"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_bool",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_uint",
+ "return_type": "uint64_t",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_int",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_real",
+ "return_type": "double",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rect2",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector3",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_transform2d",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_plane",
+ "return_type": "godot_plane",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_quat",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rect3",
+ "return_type": "godot_rect3",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_basis",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_transform",
+ "return_type": "godot_transform",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_color",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_node_path",
+ "return_type": "godot_node_path",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rid",
+ "return_type": "godot_rid",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_object",
+ "return_type": "godot_object *",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_dictionary",
+ "return_type": "godot_dictionary",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_array",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_byte_array",
+ "return_type": "godot_pool_byte_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_int_array",
+ "return_type": "godot_pool_int_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_real_array",
+ "return_type": "godot_pool_real_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_string_array",
+ "return_type": "godot_pool_string_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_vector2_array",
+ "return_type": "godot_pool_vector2_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_vector3_array",
+ "return_type": "godot_pool_vector3_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_pool_color_array",
+ "return_type": "godot_pool_color_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_call",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["godot_variant *", "p_self"],
+ ["const godot_string *", "p_method"],
+ ["const godot_variant **", "p_args"],
+ ["const godot_int", "p_argcount"],
+ ["godot_variant_call_error *", "r_error"]
+ ]
+ },
+ {
+ "name": "godot_variant_has_method",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"],
+ ["const godot_string *", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_variant_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"],
+ ["const godot_variant *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_variant_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"],
+ ["const godot_variant *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_variant_hash_compare",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"],
+ ["const godot_variant *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_variant_booleanize",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_string_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const godot_string *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_string_new_data",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_new_unicode_data",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const wchar_t *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_get_data",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["char *", "p_dest"],
+ ["int *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_operator_index",
+ "return_type": "wchar_t *",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_string_operator_index_const",
+ "return_type": "wchar_t",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_string_c_str",
+ "return_type": "const char *",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_unicode_str",
+ "return_type": "const wchar_t *",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_string_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_string_operator_plus",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_string_length",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_begins_with",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_begins_with_char_array",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const char *", "p_char_array"]
+ ]
+ },
+ {
+ "name": "godot_string_bigrams",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_chr",
+ "return_type": "godot_string",
+ "arguments": [
+ ["wchar_t", "p_character"]
+ ]
+ },
+ {
+ "name": "godot_string_ends_with",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_find",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_find_from",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_string_findmk",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_keys"]
+ ]
+ },
+ {
+ "name": "godot_string_findmk_from",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_keys"],
+ ["godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_string_findmk_from_in_place",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_keys"],
+ ["godot_int", "p_from"],
+ ["godot_int *", "r_key"]
+ ]
+ },
+ {
+ "name": "godot_string_findn",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_findn_from",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_string_find_last",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_format",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_variant *", "p_values"]
+ ]
+ },
+ {
+ "name": "godot_string_format_with_custom_placeholder",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_variant *", "p_values"],
+ ["const char *", "p_placeholder"]
+ ]
+ },
+ {
+ "name": "godot_string_hex_encode_buffer",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const uint8_t *", "p_buffer"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_hex_to_int",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_hex_to_int_without_prefix",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_insert",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_at_pos"],
+ ["godot_string", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_is_numeric",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_subsequence_of",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_is_subsequence_ofi",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_lpad",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_min_length"]
+ ]
+ },
+ {
+ "name": "godot_string_lpad_with_custom_character",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_min_length"],
+ ["const godot_string *", "p_character"]
+ ]
+ },
+ {
+ "name": "godot_string_match",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_wildcard"]
+ ]
+ },
+ {
+ "name": "godot_string_matchn",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_wildcard"]
+ ]
+ },
+ {
+ "name": "godot_string_md5",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const uint8_t *", "p_md5"]
+ ]
+ },
+ {
+ "name": "godot_string_num",
+ "return_type": "godot_string",
+ "arguments": [
+ ["double", "p_num"]
+ ]
+ },
+ {
+ "name": "godot_string_num_int64",
+ "return_type": "godot_string",
+ "arguments": [
+ ["int64_t", "p_num"],
+ ["godot_int", "p_base"]
+ ]
+ },
+ {
+ "name": "godot_string_num_int64_capitalized",
+ "return_type": "godot_string",
+ "arguments": [
+ ["int64_t", "p_num"],
+ ["godot_int", "p_base"],
+ ["godot_bool", "p_capitalize_hex"]
+ ]
+ },
+ {
+ "name": "godot_string_num_real",
+ "return_type": "godot_string",
+ "arguments": [
+ ["double", "p_num"]
+ ]
+ },
+ {
+ "name": "godot_string_num_scientific",
+ "return_type": "godot_string",
+ "arguments": [
+ ["double", "p_num"]
+ ]
+ },
+ {
+ "name": "godot_string_num_with_decimals",
+ "return_type": "godot_string",
+ "arguments": [
+ ["double", "p_num"],
+ ["godot_int", "p_decimals"]
+ ]
+ },
+ {
+ "name": "godot_string_pad_decimals",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_digits"]
+ ]
+ },
+ {
+ "name": "godot_string_pad_zeros",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_digits"]
+ ]
+ },
+ {
+ "name": "godot_string_replace_first",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_key"],
+ ["godot_string", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_string_replace",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_key"],
+ ["godot_string", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_string_replacen",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_key"],
+ ["godot_string", "p_with"]
+ ]
+ },
+ {
+ "name": "godot_string_rfind",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_rfindn",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_rfind_from",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_string_rfindn_from",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"]
+ ]
+ },
+ {
+ "name": "godot_string_rpad",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_min_length"]
+ ]
+ },
+ {
+ "name": "godot_string_rpad_with_custom_character",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_min_length"],
+ ["const godot_string *", "p_character"]
+ ]
+ },
+ {
+ "name": "godot_string_similarity",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_string"]
+ ]
+ },
+ {
+ "name": "godot_string_sprintf",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_values"],
+ ["godot_bool *", "p_error"]
+ ]
+ },
+ {
+ "name": "godot_string_substr",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_chars"]
+ ]
+ },
+ {
+ "name": "godot_string_to_double",
+ "return_type": "double",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_to_float",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_to_int",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_camelcase_to_underscore",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_camelcase_to_underscore_lowercased",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_capitalize",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_char_to_double",
+ "return_type": "double",
+ "arguments": [
+ ["const char *", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_char_to_int",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const char *", "p_what"]
+ ]
+ },
+ {
+ "name": "godot_string_wchar_to_int",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const wchar_t *", "p_str"]
+ ]
+ },
+ {
+ "name": "godot_string_char_to_int_with_len",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const char *", "p_what"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_char_to_int64_with_len",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const wchar_t *", "p_str"],
+ ["int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_hex_to_int64",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_hex_to_int64_with_prefix",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_to_int64",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_unicode_char_to_double",
+ "return_type": "double",
+ "arguments": [
+ ["const wchar_t *", "p_str"],
+ ["const wchar_t **", "r_end"]
+ ]
+ },
+ {
+ "name": "godot_string_get_slice_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_get_slice",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_splitter"],
+ ["godot_int", "p_slice"]
+ ]
+ },
+ {
+ "name": "godot_string_get_slicec",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["wchar_t", "p_splitter"],
+ ["godot_int", "p_slice"]
+ ]
+ },
+ {
+ "name": "godot_string_split",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_allow_empty",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_floats",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_floats_allows_empty",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_floats_mk",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_splitters"]
+ ]
+ },
+ {
+ "name": "godot_string_split_floats_mk_allows_empty",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_splitters"]
+ ]
+ },
+ {
+ "name": "godot_string_split_ints",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_ints_allows_empty",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_split_ints_mk",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_splitters"]
+ ]
+ },
+ {
+ "name": "godot_string_split_ints_mk_allows_empty",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_array *", "p_splitters"]
+ ]
+ },
+ {
+ "name": "godot_string_split_spaces",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_char_lowercase",
+ "return_type": "wchar_t",
+ "arguments": [
+ ["wchar_t", "p_char"]
+ ]
+ },
+ {
+ "name": "godot_string_char_uppercase",
+ "return_type": "wchar_t",
+ "arguments": [
+ ["wchar_t", "p_char"]
+ ]
+ },
+ {
+ "name": "godot_string_to_lower",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_to_upper",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_get_basename",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_get_extension",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_left",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_pos"]
+ ]
+ },
+ {
+ "name": "godot_string_ord_at",
+ "return_type": "wchar_t",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_string_plus_file",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_file"]
+ ]
+ },
+ {
+ "name": "godot_string_right",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_pos"]
+ ]
+ },
+ {
+ "name": "godot_string_strip_edges",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_bool", "p_left"],
+ ["godot_bool", "p_right"]
+ ]
+ },
+ {
+ "name": "godot_string_strip_escapes",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_erase",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["godot_int", "p_pos"],
+ ["godot_int", "p_chars"]
+ ]
+ },
+ {
+ "name": "godot_string_ascii",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["char *", "result"]
+ ]
+ },
+ {
+ "name": "godot_string_ascii_extended",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["char *", "result"]
+ ]
+ },
+ {
+ "name": "godot_string_utf8",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["char *", "result"]
+ ]
+ },
+ {
+ "name": "godot_string_parse_utf8",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["const char *", "p_utf8"]
+ ]
+ },
+ {
+ "name": "godot_string_parse_utf8_with_len",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["const char *", "p_utf8"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_chars_to_utf8",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const char *", "p_utf8"]
+ ]
+ },
+ {
+ "name": "godot_string_chars_to_utf8_with_len",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const char *", "p_utf8"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_hash",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_hash64",
+ "return_type": "uint64_t",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_hash_chars",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const char *", "p_cstr"]
+ ]
+ },
+ {
+ "name": "godot_string_hash_chars_with_len",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const char *", "p_cstr"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_hash_utf8_chars",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const wchar_t *", "p_str"]
+ ]
+ },
+ {
+ "name": "godot_string_hash_utf8_chars_with_len",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const wchar_t *", "p_str"],
+ ["godot_int", "p_len"]
+ ]
+ },
+ {
+ "name": "godot_string_md5_buffer",
+ "return_type": "godot_pool_byte_array",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_md5_text",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_sha256_buffer",
+ "return_type": "godot_pool_byte_array",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_sha256_text",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_get_base_dir",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_get_file",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_humanize_size",
+ "return_type": "godot_string",
+ "arguments": [
+ ["size_t", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_is_abs_path",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_rel_path",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_resource_file",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_path_to",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_path"]
+ ]
+ },
+ {
+ "name": "godot_string_path_to_file",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_path"]
+ ]
+ },
+ {
+ "name": "godot_string_simplify_path",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_c_escape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_c_escape_multiline",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_c_unescape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_http_escape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_http_unescape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_json_escape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_word_wrap",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_chars_per_line"]
+ ]
+ },
+ {
+ "name": "godot_string_xml_escape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_xml_escape_with_quotes",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_xml_unescape",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_percent_decode",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_percent_encode",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_float",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_hex_number",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_bool", "p_with_prefix"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_html_color",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_identifier",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_integer",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_ip_address",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_name_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string_name *", "r_dest"],
+ ["const godot_string *", "p_name"]
+ ]
+ },
+ {
+ "name": "godot_string_name_new_data",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string_name *", "r_dest"],
+ ["const char *", "p_name"]
+ ]
+ },
+ {
+ "name": "godot_string_name_get_name",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string_name *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_name_get_hash",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const godot_string_name *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_name_get_data_unique_pointer",
+ "return_type": "const void *",
+ "arguments": [
+ ["const godot_string_name *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_name_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string_name *", "p_self"],
+ ["const godot_string_name *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_string_name_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string_name *", "p_self"],
+ ["const godot_string_name *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_string_name_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string_name *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_object_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_object *", "p_o"]
+ ]
+ },
+ {
+ "name": "godot_global_get_singleton",
+ "return_type": "godot_object *",
+ "arguments": [
+ ["char *", "p_name"]
+ ]
+ },
+ {
+ "name": "godot_method_bind_get_method",
+ "return_type": "godot_method_bind *",
+ "arguments": [
+ ["const char *", "p_classname"],
+ ["const char *", "p_methodname"]
+ ]
+ },
+ {
+ "name": "godot_method_bind_ptrcall",
+ "return_type": "void",
+ "arguments": [
+ ["godot_method_bind *", "p_method_bind"],
+ ["godot_object *", "p_instance"],
+ ["const void **", "p_args"],
+ ["void *", "p_ret"]
+ ]
+ },
+ {
+ "name": "godot_method_bind_call",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["godot_method_bind *", "p_method_bind"],
+ ["godot_object *", "p_instance"],
+ ["const godot_variant **", "p_args"],
+ ["const int", "p_arg_count"],
+ ["godot_variant_call_error *", "p_call_error"]
+ ]
+ },
+ {
+ "name": "godot_get_class_constructor",
+ "return_type": "godot_class_constructor",
+ "arguments": [
+ ["const char *", "p_classname"]
+ ]
+ },
+ {
+ "name": "godot_alloc",
+ "return_type": "void *",
+ "arguments": [
+ ["int", "p_bytes"]
+ ]
+ },
+ {
+ "name": "godot_realloc",
+ "return_type": "void *",
+ "arguments": [
+ ["void *", "p_ptr"],
+ ["int", "p_bytes"]
+ ]
+ },
+ {
+ "name": "godot_free",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_ptr"]
+ ]
+ },
+ {
+ "name": "godot_print_error",
+ "return_type": "void",
+ "arguments": [
+ ["const char *", "p_description"],
+ ["const char *", "p_function"],
+ ["const char *", "p_file"],
+ ["int", "p_line"]
+ ]
+ },
+ {
+ "name": "godot_print_warning",
+ "return_type": "void",
+ "arguments": [
+ ["const char *", "p_description"],
+ ["const char *", "p_function"],
+ ["const char *", "p_file"],
+ ["int", "p_line"]
+ ]
+ },
+ {
+ "name": "godot_print",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_string *", "p_message"]
+ ]
+ }
+ ]
+ },
+ "extensions": {
+ "nativescript": {
+ "type": "NATIVESCRIPT",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "api": [
+ {
+ "name": "godot_nativescript_register_class",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_gdnative_handle"],
+ ["const char *", "p_name"],
+ ["const char *", "p_base"],
+ ["godot_instance_create_func", "p_create_func"],
+ ["godot_instance_destroy_func", "p_destroy_func"]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_tool_class",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_gdnative_handle"],
+ ["const char *", "p_name"],
+ ["const char *", "p_base"],
+ ["godot_instance_create_func", "p_create_func"],
+ ["godot_instance_destroy_func", "p_destroy_func"]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_method",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_gdnative_handle"],
+ ["const char *", "p_name"],
+ ["const char *", "p_function_name"],
+ ["godot_method_attributes", "p_attr"],
+ ["godot_instance_method", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_property",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_gdnative_handle"],
+ ["const char *", "p_name"],
+ ["const char *", "p_path"],
+ ["godot_property_attributes *", "p_attr"],
+ ["godot_property_set_func", "p_set_func"],
+ ["godot_property_get_func", "p_get_func"]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_signal",
+ "return_type": "void",
+ "arguments": [
+ ["void *", "p_gdnative_handle"],
+ ["const char *", "p_name"],
+ ["const godot_signal *", "p_signal"]
+ ]
+ },
+ {
+ "name": "godot_nativescript_get_userdata",
+ "return_type": "void *",
+ "arguments": [
+ ["godot_object *", "p_instance"]
+ ]
+ }
+ ]
+ },
+ "pluginscript": {
+ "type": "PLUGINSCRIPT",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "api": [
+ {
+ "name": "godot_pluginscript_register_language",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_pluginscript_language_desc *", "language_desc"]
+ ]
+ }
+ ]
+ },
+ "arvr": {
+ "type": "ARVR",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "api": [
+ {
+ "name": "godot_arvr_register_interface",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_arvr_interface_gdnative *", "p_interface"]
+ ]
+ },
+ {
+ "name": "godot_arvr_get_worldscale",
+ "return_type": "godot_real",
+ "arguments": []
+ },
+ {
+ "name": "godot_arvr_get_reference_frame",
+ "return_type": "godot_transform",
+ "arguments": []
+ },
+ {
+ "name": "godot_arvr_blit",
+ "return_type": "void",
+ "arguments": [
+ ["int", "p_eye"],
+ ["godot_rid *", "p_render_target"],
+ ["godot_rect2 *", "p_screen_rect"]
+ ]
+ },
+ {
+ "name": "godot_arvr_get_texid",
+ "return_type": "godot_int",
+ "arguments": [
+ ["godot_rid *", "p_render_target"]
+ ]
+ },
+ {
+ "name": "godot_arvr_add_controller",
+ "return_type": "godot_int",
+ "arguments": [
+ ["char *", "p_device_name"],
+ ["godot_int", "p_hand"],
+ ["godot_bool", "p_tracks_orientation"],
+ ["godot_bool", "p_tracks_position"]
+ ]
+ },
+ {
+ "name": "godot_arvr_remove_controller",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_transform",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_transform *", "p_transform"],
+ ["godot_bool", "p_tracks_orientation"],
+ ["godot_bool", "p_tracks_position"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_button",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_int", "p_button"],
+ ["godot_bool", "p_is_pressed"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_axis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_int", "p_exis"],
+ ["godot_real", "p_value"],
+ ["godot_bool", "p_can_be_negative"]
+ ]
+ },
+ {
+ "name": "godot_arvr_get_controller_rumble",
+ "return_type": "godot_real",
+ "arguments": [
+ ["godot_int", "p_controller_id"]
+ ]
+ }
]
}
- ]
+ }
}
diff --git a/modules/gdnative/include/nativearvr/godot_nativearvr.h b/modules/gdnative/include/arvr/godot_arvr.h
index f86919f33a..be13ac954b 100644
--- a/modules/gdnative/include/nativearvr/godot_nativearvr.h
+++ b/modules/gdnative/include/arvr/godot_arvr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_nativearvr.h */
+/* godot_arvr.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -36,6 +36,26 @@
extern "C" {
#endif
+typedef struct {
+ void *(*constructor)(godot_object *);
+ void (*destructor)(void *);
+ godot_string (*get_name)(const void *);
+ godot_int (*get_capabilities)(const void *);
+ godot_bool (*get_anchor_detection_is_enabled)(const void *);
+ void (*set_anchor_detection_is_enabled)(void *, godot_bool);
+ godot_bool (*is_stereo)(const void *);
+ godot_bool (*is_initialized)(const void *);
+ godot_bool (*initialize)(void *);
+ void (*uninitialize)(void *);
+ godot_vector2 (*get_render_targetsize)(const void *);
+ godot_transform (*get_transform_for_eye)(void *, godot_int, godot_transform *);
+ void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real);
+ void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *);
+ void (*process)(void *);
+} godot_arvr_interface_gdnative;
+
+void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface);
+
// helper functions to access ARVRServer data
godot_real GDAPI godot_arvr_get_worldscale();
godot_transform GDAPI godot_arvr_get_reference_frame();
@@ -50,9 +70,10 @@ void GDAPI godot_arvr_remove_controller(godot_int p_controller_id);
void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
+godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id);
#ifdef __cplusplus
}
#endif
-#endif /* !GODOT_NATIVEARVR_H */ \ No newline at end of file
+#endif /* !GODOT_NATIVEARVR_H */
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index edab028cba..01ae61e280 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -46,11 +46,20 @@ typedef struct {
} godot_array;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/pool_arrays.h>
#include <gdnative/variant.h>
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_array_new(godot_array *r_dest);
void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca);
@@ -67,6 +76,8 @@ godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p
godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx);
+const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx);
+
void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value);
void GDAPI godot_array_clear(godot_array *p_self);
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index 8ff6a6f541..49ca765a01 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_basis;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/quat.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler);
@@ -88,7 +97,7 @@ void GDAPI godot_basis_new(godot_basis *r_dest);
void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler);
// p_elements is a pointer to an array of 3 (!!) vector3
-void GDAPI godot_basis_get_elements(godot_basis *p_self, godot_vector3 *p_elements);
+void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements);
godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis);
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 14265466b9..857e86a738 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_color;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a);
void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index c85c3f3830..6d1f436921 100644
--- a/modules/gdnative/include/gdnative/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_dictionary;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
void GDAPI godot_dictionary_destroy(godot_dictionary *p_self);
@@ -76,6 +85,8 @@ void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p
godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key);
+const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key);
+
godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key);
godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b);
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 2d8726e5db..8fa96fd3af 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -47,7 +47,7 @@ extern "C" {
#define GDAPI GDCALLINGCONV
#endif
#else
-#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
+#define GDCALLINGCONV __attribute__((sysv_abi))
#define GDAPI GDCALLINGCONV
#endif
@@ -237,7 +237,7 @@ typedef struct {
uint64_t editor_api_hash;
uint64_t no_api_hash;
godot_object *gd_native_library; // pointer to GDNativeLibrary that is being initialized
- const struct godot_gdnative_api_struct *api_struct;
+ const struct godot_gdnative_core_api_struct *api_struct;
const godot_string *active_library_path;
} godot_gdnative_init_options;
@@ -255,7 +255,7 @@ godot_dictionary GDAPI godot_get_global_constants();
////// GDNative procedure types
typedef void (*godot_gdnative_init_fn)(godot_gdnative_init_options *);
typedef void (*godot_gdnative_terminate_fn)(godot_gdnative_terminate_options *);
-typedef godot_variant (*godot_gdnative_procedure_fn)(void *, godot_array *);
+typedef godot_variant (*godot_gdnative_procedure_fn)(godot_array *);
////// System Functions
diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h
index 0cfdbc1127..42446175d8 100644
--- a/modules/gdnative/include/gdnative/node_path.h
+++ b/modules/gdnative/include/gdnative/node_path.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_node_path;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from);
void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src);
void GDAPI godot_node_path_destroy(godot_node_path *p_self);
diff --git a/modules/gdnative/include/gdnative/plane.h b/modules/gdnative/include/gdnative/plane.h
index 6a8915e08b..dddd172122 100644
--- a/modules/gdnative/include/gdnative/plane.h
+++ b/modules/gdnative/include/gdnative/plane.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_plane;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d);
void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3);
void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d);
diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h
index cb1095ee8c..81500c9186 100644
--- a/modules/gdnative/include/gdnative/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/pool_arrays.h
@@ -36,6 +36,38 @@ extern "C" {
#include <stdint.h>
+/////// Read Access
+
+#define GODOT_POOL_ARRAY_READ_ACCESS_SIZE 1
+
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_POOL_ARRAY_READ_ACCESS_SIZE];
+} godot_pool_array_read_access;
+
+typedef godot_pool_array_read_access godot_pool_byte_array_read_access;
+typedef godot_pool_array_read_access godot_pool_int_array_read_access;
+typedef godot_pool_array_read_access godot_pool_real_array_read_access;
+typedef godot_pool_array_read_access godot_pool_string_array_read_access;
+typedef godot_pool_array_read_access godot_pool_vector2_array_read_access;
+typedef godot_pool_array_read_access godot_pool_vector3_array_read_access;
+typedef godot_pool_array_read_access godot_pool_color_array_read_access;
+
+/////// Write Access
+
+#define GODOT_POOL_ARRAY_WRITE_ACCESS_SIZE 1
+
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_POOL_ARRAY_WRITE_ACCESS_SIZE];
+} godot_pool_array_write_access;
+
+typedef godot_pool_array_write_access godot_pool_byte_array_write_access;
+typedef godot_pool_array_write_access godot_pool_int_array_write_access;
+typedef godot_pool_array_write_access godot_pool_real_array_write_access;
+typedef godot_pool_array_write_access godot_pool_string_array_write_access;
+typedef godot_pool_array_write_access godot_pool_vector2_array_write_access;
+typedef godot_pool_array_write_access godot_pool_vector3_array_write_access;
+typedef godot_pool_array_write_access godot_pool_color_array_write_access;
+
/////// PoolByteArray
#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *)
@@ -113,6 +145,11 @@ typedef struct {
} godot_pool_color_array;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/color.h>
#include <gdnative/vector2.h>
@@ -120,6 +157,10 @@ typedef struct {
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// byte
void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest);
@@ -140,6 +181,10 @@ void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_self, const god
void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const godot_int p_size);
+godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read(const godot_pool_byte_array *p_self);
+
+godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write(godot_pool_byte_array *p_self);
+
void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, const godot_int p_idx);
@@ -167,6 +212,10 @@ void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_self, const godot
void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot_int p_size);
+godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read(const godot_pool_int_array *p_self);
+
+godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write(godot_pool_int_array *p_self);
+
void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data);
godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, const godot_int p_idx);
@@ -194,6 +243,10 @@ void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const god
void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size);
+godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read(const godot_pool_real_array *p_self);
+
+godot_pool_real_array_write_access GDAPI *godot_pool_real_array_write(godot_pool_real_array *p_self);
+
void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data);
godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self, const godot_int p_idx);
@@ -221,6 +274,10 @@ void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_self, const
void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const godot_int p_size);
+godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read(const godot_pool_string_array *p_self);
+
+godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write(godot_pool_string_array *p_self);
+
void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_self, const godot_int p_idx);
@@ -248,6 +305,10 @@ void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_self, con
void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, const godot_int p_size);
+godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read(const godot_pool_vector2_array *p_self);
+
+godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write(godot_pool_vector2_array *p_self);
+
void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array *p_self, const godot_int p_idx);
@@ -275,6 +336,10 @@ void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_self, con
void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, const godot_int p_size);
+godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read(const godot_pool_vector3_array *p_self);
+
+godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write(godot_pool_vector3_array *p_self);
+
void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array *p_self, const godot_int p_idx);
@@ -302,6 +367,10 @@ void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_self, const g
void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const godot_int p_size);
+godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read(const godot_pool_color_array *p_self);
+
+godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write(godot_pool_color_array *p_self);
+
void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_self, const godot_int p_idx);
@@ -309,6 +378,70 @@ godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self
void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self);
+//
+// read accessor functions
+//
+
+const uint8_t GDAPI *godot_pool_byte_array_read_access_ptr(const godot_pool_byte_array_read_access *p_read);
+void GDAPI godot_pool_byte_array_read_access_operator_assign(godot_pool_byte_array_read_access *p_read, godot_pool_byte_array_read_access *p_other);
+void GDAPI godot_pool_byte_array_read_access_destroy(godot_pool_byte_array_read_access *p_read);
+
+const godot_int GDAPI *godot_pool_int_array_read_access_ptr(const godot_pool_int_array_read_access *p_read);
+void GDAPI godot_pool_int_array_read_access_operator_assign(godot_pool_int_array_read_access *p_read, godot_pool_int_array_read_access *p_other);
+void GDAPI godot_pool_int_array_read_access_destroy(godot_pool_int_array_read_access *p_read);
+
+const godot_real GDAPI *godot_pool_real_array_read_access_ptr(const godot_pool_real_array_read_access *p_read);
+void GDAPI godot_pool_real_array_read_access_operator_assign(godot_pool_real_array_read_access *p_read, godot_pool_real_array_read_access *p_other);
+void GDAPI godot_pool_real_array_read_access_destroy(godot_pool_real_array_read_access *p_read);
+
+const godot_string GDAPI *godot_pool_string_array_read_access_ptr(const godot_pool_string_array_read_access *p_read);
+void GDAPI godot_pool_string_array_read_access_operator_assign(godot_pool_string_array_read_access *p_read, godot_pool_string_array_read_access *p_other);
+void GDAPI godot_pool_string_array_read_access_destroy(godot_pool_string_array_read_access *p_read);
+
+const godot_vector2 GDAPI *godot_pool_vector2_array_read_access_ptr(const godot_pool_vector2_array_read_access *p_read);
+void GDAPI godot_pool_vector2_array_read_access_operator_assign(godot_pool_vector2_array_read_access *p_read, godot_pool_vector2_array_read_access *p_other);
+void GDAPI godot_pool_vector2_array_read_access_destroy(godot_pool_vector2_array_read_access *p_read);
+
+const godot_vector3 GDAPI *godot_pool_vector3_array_read_access_ptr(const godot_pool_vector3_array_read_access *p_read);
+void GDAPI godot_pool_vector3_array_read_access_operator_assign(godot_pool_vector3_array_read_access *p_read, godot_pool_vector3_array_read_access *p_other);
+void GDAPI godot_pool_vector3_array_read_access_destroy(godot_pool_vector3_array_read_access *p_read);
+
+const godot_color GDAPI *godot_pool_color_array_read_access_ptr(const godot_pool_color_array_read_access *p_read);
+void GDAPI godot_pool_color_array_read_access_operator_assign(godot_pool_color_array_read_access *p_read, godot_pool_color_array_read_access *p_other);
+void GDAPI godot_pool_color_array_read_access_destroy(godot_pool_color_array_read_access *p_read);
+
+//
+// write accessor functions
+//
+
+uint8_t GDAPI *godot_pool_byte_array_write_access_ptr(const godot_pool_byte_array_write_access *p_write);
+void GDAPI godot_pool_byte_array_write_access_operator_assign(godot_pool_byte_array_write_access *p_write, godot_pool_byte_array_write_access *p_other);
+void GDAPI godot_pool_byte_array_write_access_destroy(godot_pool_byte_array_write_access *p_write);
+
+godot_int GDAPI *godot_pool_int_array_write_access_ptr(const godot_pool_int_array_write_access *p_write);
+void GDAPI godot_pool_int_array_write_access_operator_assign(godot_pool_int_array_write_access *p_write, godot_pool_int_array_write_access *p_other);
+void GDAPI godot_pool_int_array_write_access_destroy(godot_pool_int_array_write_access *p_write);
+
+godot_real GDAPI *godot_pool_real_array_write_access_ptr(const godot_pool_real_array_write_access *p_write);
+void GDAPI godot_pool_real_array_write_access_operator_assign(godot_pool_real_array_write_access *p_write, godot_pool_real_array_write_access *p_other);
+void GDAPI godot_pool_real_array_write_access_destroy(godot_pool_real_array_write_access *p_write);
+
+godot_string GDAPI *godot_pool_string_array_write_access_ptr(const godot_pool_string_array_write_access *p_write);
+void GDAPI godot_pool_string_array_write_access_operator_assign(godot_pool_string_array_write_access *p_write, godot_pool_string_array_write_access *p_other);
+void GDAPI godot_pool_string_array_write_access_destroy(godot_pool_string_array_write_access *p_write);
+
+godot_vector2 GDAPI *godot_pool_vector2_array_write_access_ptr(const godot_pool_vector2_array_write_access *p_write);
+void GDAPI godot_pool_vector2_array_write_access_operator_assign(godot_pool_vector2_array_write_access *p_write, godot_pool_vector2_array_write_access *p_other);
+void GDAPI godot_pool_vector2_array_write_access_destroy(godot_pool_vector2_array_write_access *p_write);
+
+godot_vector3 GDAPI *godot_pool_vector3_array_write_access_ptr(const godot_pool_vector3_array_write_access *p_write);
+void GDAPI godot_pool_vector3_array_write_access_operator_assign(godot_pool_vector3_array_write_access *p_write, godot_pool_vector3_array_write_access *p_other);
+void GDAPI godot_pool_vector3_array_write_access_destroy(godot_pool_vector3_array_write_access *p_write);
+
+godot_color GDAPI *godot_pool_color_array_write_access_ptr(const godot_pool_color_array_write_access *p_write);
+void GDAPI godot_pool_color_array_write_access_operator_assign(godot_pool_color_array_write_access *p_write, godot_pool_color_array_write_access *p_other);
+void GDAPI godot_pool_color_array_write_access_destroy(godot_pool_color_array_write_access *p_write);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index 4ffb96eb26..acae6e3e90 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_quat;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w);
void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 9e6cf60342..1c66443d4f 100644
--- a/modules/gdnative/include/gdnative/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -43,9 +43,18 @@ typedef struct godot_rect2 {
} godot_rect2;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector2.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
diff --git a/modules/gdnative/include/gdnative/rect3.h b/modules/gdnative/include/gdnative/rect3.h
index f94b6fea25..f603a9268a 100644
--- a/modules/gdnative/include/gdnative/rect3.h
+++ b/modules/gdnative/include/gdnative/rect3.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_rect3;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/plane.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size);
godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self);
diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h
index d9b5336fc9..caa1bb967e 100644
--- a/modules/gdnative/include/gdnative/rid.h
+++ b/modules/gdnative/include/gdnative/rid.h
@@ -45,8 +45,17 @@ typedef struct {
} godot_rid;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rid_new(godot_rid *r_dest);
godot_int GDAPI godot_rid_get_id(const godot_rid *p_self);
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index aca23a81d8..29510313c9 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -46,9 +46,18 @@ typedef struct {
} godot_string;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_string_new(godot_string *r_dest);
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size);
@@ -57,6 +66,7 @@ void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_
void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int *p_size);
wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx);
+wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx);
const char GDAPI *godot_string_c_str(const godot_string *p_self);
const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self);
diff --git a/modules/gdnative/include/gdnative/string_name.h b/modules/gdnative/include/gdnative/string_name.h
index e217487250..ee9f603d20 100644
--- a/modules/gdnative/include/gdnative/string_name.h
+++ b/modules/gdnative/include/gdnative/string_name.h
@@ -46,8 +46,17 @@ typedef struct {
} godot_string_name;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name);
void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name);
diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h
index 656afae129..8f50b01fb5 100644
--- a/modules/gdnative/include/gdnative/transform.h
+++ b/modules/gdnative/include/gdnative/transform.h
@@ -45,11 +45,20 @@ typedef struct {
} godot_transform;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin);
void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h
index a945868b17..c68bd2963f 100644
--- a/modules/gdnative/include/gdnative/transform2d.h
+++ b/modules/gdnative/include/gdnative/transform2d.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_transform2d;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
#include <gdnative/vector2.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos);
void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin);
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index 7b804c1eaf..3d744ef1f2 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -99,6 +99,11 @@ typedef struct godot_variant_call_error {
godot_variant_type expected;
} godot_variant_call_error;
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/basis.h>
#include <gdnative/color.h>
@@ -119,6 +124,10 @@ typedef struct godot_variant_call_error {
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
void GDAPI godot_variant_new_copy(godot_variant *r_dest, const godot_variant *p_src);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 0af4abae27..07105abaf2 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -45,8 +45,17 @@ typedef struct {
} godot_vector2;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index a27d516ec5..3ed23778ec 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_vector3;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef enum {
GODOT_VECTOR3_AXIS_X,
GODOT_VECTOR3_AXIS_Y,
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
new file mode 100644
index 0000000000..d1c210529c
--- /dev/null
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* godot_nativescript.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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_PLUGINSCRIPT_H
+#define GODOT_PLUGINSCRIPT_H
+
+#include <gdnative/gdnative.h>
+#include <nativescript/godot_nativescript.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void godot_pluginscript_instance_data;
+typedef void godot_pluginscript_script_data;
+typedef void godot_pluginscript_language_data;
+
+// --- Instance ---
+
+// TODO: use godot_string_name for faster lookup ?
+typedef struct {
+ godot_pluginscript_instance_data *(*init)(godot_pluginscript_script_data *p_data, godot_object *p_owner);
+ void (*finish)(godot_pluginscript_instance_data *p_data);
+
+ godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, const godot_variant *p_value);
+ godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, godot_variant *r_ret);
+
+ godot_variant (*call_method)(godot_pluginscript_instance_data *p_data,
+ const godot_string_name *p_method, const godot_variant **p_args,
+ int p_argcount, godot_variant_call_error *r_error);
+
+ void (*notification)(godot_pluginscript_instance_data *p_data, int p_notification);
+ // TODO: could this rpc mode stuff be moved to the godot_pluginscript_script_manifest ?
+ godot_method_rpc_mode (*get_rpc_mode)(godot_pluginscript_instance_data *p_data, const godot_string *p_method);
+ godot_method_rpc_mode (*get_rset_mode)(godot_pluginscript_instance_data *p_data, const godot_string *p_variable);
+
+ //this is used by script languages that keep a reference counter of their own
+ //you can make make Ref<> not die when it reaches zero, so deleting the reference
+ //depends entirely from the script.
+ // Note: You can set thoses function pointer to NULL if not needed.
+ void (*refcount_incremented)(godot_pluginscript_instance_data *p_data);
+ bool (*refcount_decremented)(godot_pluginscript_instance_data *p_data); // return true if it can die
+} godot_pluginscript_instance_desc;
+
+// --- Script ---
+
+typedef struct {
+ godot_pluginscript_script_data *data;
+ godot_string_name name;
+ godot_bool is_tool;
+ godot_string_name base;
+
+ // Member lines format: {<string>: <int>}
+ godot_dictionary member_lines;
+ // Method info dictionary format
+ // {
+ // name: <string>
+ // args: [<dict:property>]
+ // default_args: [<variant>]
+ // return: <dict:property>
+ // flags: <int>
+ // rpc_mode: <int:godot_method_rpc_mode>
+ // }
+ godot_array methods;
+ // Same format than for methods
+ godot_array signals;
+ // Property info dictionary format
+ // {
+ // name: <string>
+ // type: <int:godot_variant_type>
+ // hint: <int:godot_property_hint>
+ // hint_string: <string>
+ // usage: <int:godot_property_usage_flags>
+ // default_value: <variant>
+ // rset_mode: <int:godot_method_rpc_mode>
+ // }
+ godot_array properties;
+} godot_pluginscript_script_manifest;
+
+typedef struct {
+ godot_pluginscript_script_manifest (*init)(godot_pluginscript_language_data *p_data, const godot_string *p_path, const godot_string *p_source, godot_error *r_error);
+ void (*finish)(godot_pluginscript_script_data *p_data);
+ godot_pluginscript_instance_desc instance_desc;
+} godot_pluginscript_script_desc;
+
+// --- Language ---
+
+typedef struct {
+ godot_string_name signature;
+ godot_int call_count;
+ godot_int total_time; // In microseconds
+ godot_int self_time; // In microseconds
+} godot_pluginscript_profiling_data;
+
+typedef struct {
+ const char *name;
+ const char *type;
+ const char *extension;
+ const char **recognized_extensions; // NULL terminated array
+ godot_pluginscript_language_data *(*init)();
+ void (*finish)(godot_pluginscript_language_data *p_data);
+ const char **reserved_words; // NULL terminated array
+ const char **comment_delimiters; // NULL terminated array
+ const char **string_delimiters; // NULL terminated array
+ godot_bool has_named_classes;
+ godot_bool supports_builtin_mode;
+
+ godot_string (*get_template_source_code)(godot_pluginscript_language_data *p_data, const godot_string *p_class_name, const godot_string *p_base_class_name);
+ godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_pool_string_array *r_functions);
+ int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be NULL
+ godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_pool_string_array *p_args);
+ godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_base_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
+ void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line);
+
+ void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value);
+ godot_string (*debug_get_error)(godot_pluginscript_language_data *p_data);
+ int (*debug_get_stack_level_count)(godot_pluginscript_language_data *p_data);
+ int (*debug_get_stack_level_line)(godot_pluginscript_language_data *p_data, int p_level);
+ godot_string (*debug_get_stack_level_function)(godot_pluginscript_language_data *p_data, int p_level);
+ godot_string (*debug_get_stack_level_source)(godot_pluginscript_language_data *p_data, int p_level);
+ void (*debug_get_stack_level_locals)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_stack_level_members)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_members, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_globals)(godot_pluginscript_language_data *p_data, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ godot_string (*debug_parse_stack_level_expression)(godot_pluginscript_language_data *p_data, int p_level, const godot_string *p_expression, int p_max_subitems, int p_max_depth);
+
+ // TODO: could this stuff be moved to the godot_pluginscript_language_desc ?
+ void (*get_public_functions)(godot_pluginscript_language_data *p_data, godot_array *r_functions);
+ void (*get_public_constants)(godot_pluginscript_language_data *p_data, godot_dictionary *r_constants);
+
+ void (*profiling_start)(godot_pluginscript_language_data *p_data);
+ void (*profiling_stop)(godot_pluginscript_language_data *p_data);
+ int (*profiling_get_accumulated_data)(godot_pluginscript_language_data *p_data, godot_pluginscript_profiling_data *r_info, int p_info_max);
+ int (*profiling_get_frame_data)(godot_pluginscript_language_data *p_data, godot_pluginscript_profiling_data *r_info, int p_info_max);
+ void (*profiling_frame)(godot_pluginscript_language_data *p_data);
+
+ godot_pluginscript_script_desc script_desc;
+} godot_pluginscript_language_desc;
+
+void GDAPI godot_pluginscript_register_language(const godot_pluginscript_language_desc *language_desc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_PLUGINSCRIPT_H
diff --git a/modules/gdnative/nativearvr/register_types.cpp b/modules/gdnative/nativearvr/register_types.cpp
deleted file mode 100644
index f4dc13ed55..0000000000
--- a/modules/gdnative/nativearvr/register_types.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-/*************************************************************************/
-/* register_types.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 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 "arvr_interface_gdnative.h"
-#include "core/os/os.h"
-
-void arvr_call_constructor(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- void *(*proc)(godot_object *);
- proc = (void *(*)(godot_object *))library_proc;
-
- godot_object *this_object = (godot_object *)p_args[0];
- void *p = proc(this_object);
-
- void **return_ptr = (void **)r_return;
-
- *return_ptr = p;
-};
-
-void arvr_call_destructor(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- void (*proc)(void *);
- proc = (void (*)(void *))library_proc;
-
- proc(p_data);
-};
-
-void arvr_return_string(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_string (*proc)(void *);
- proc = (godot_string(*)(void *))library_proc;
-
- godot_string s = proc(p_data);
-
- StringName *return_ptr = (StringName *)r_return;
-
- String *returned_string = (String *)&s;
-
- *return_ptr = *returned_string;
-
- godot_string_destroy(&s);
-};
-
-void arvr_return_int(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_int (*proc)(void *);
- proc = (godot_int(*)(void *))library_proc;
-
- godot_int i = proc(p_data);
-
- int *return_ptr = (int *)r_return;
-
- *return_ptr = i;
-};
-
-void arvr_return_bool(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_bool (*proc)(void *);
- proc = (godot_bool(*)(void *))library_proc;
-
- godot_bool b = proc(p_data);
-
- int *return_ptr = (int *)r_return;
-
- *return_ptr = b;
-};
-
-void arvr_set_bool(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- void (*proc)(void *, bool);
- proc = (void (*)(void *, bool))library_proc;
-
- bool *set_bool = (bool *)p_args[0];
- proc(p_data, *set_bool);
-};
-
-void arvr_call_method(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_bool (*proc)(void *);
- proc = (godot_bool(*)(void *))library_proc;
-
- proc(p_data);
-};
-
-void arvr_return_vector2(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_vector2 (*proc)(void *);
- proc = (godot_vector2(*)(void *))library_proc;
-
- godot_vector2 v = proc(p_data);
-
- godot_vector2 *return_ptr = (godot_vector2 *)r_return;
-
- *return_ptr = v;
-};
-
-void arvr_return_transform_for_eye(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- godot_transform (*proc)(void *, int, godot_transform *);
- proc = (godot_transform(*)(void *, int, godot_transform *))library_proc;
-
- int *eye = (int *)p_args[0];
- godot_transform *camera_transform = (godot_transform *)p_args[1];
- godot_transform t = proc(p_data, *eye, camera_transform);
-
- godot_transform *return_ptr = (godot_transform *)r_return;
-
- *return_ptr = t;
-};
-
-void arvr_call_fill_projection_for_eye(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- void (*proc)(void *, real_t *, int, real_t, real_t, real_t);
- proc = (void (*)(void *, real_t *, int, real_t, real_t, real_t))library_proc;
-
- real_t *projection = (real_t *)p_args[0]; // <-- we'll be writing into this buffer, must have enough space for 16 floats!
- int *eye = (int *)p_args[1];
- real_t *aspect = (real_t *)p_args[2];
- real_t *zn = (real_t *)p_args[3];
- real_t *zf = (real_t *)p_args[4];
-
- proc(p_data, projection, *eye, *aspect, *zn, *zf);
-};
-
-void arvr_call_commit_for_eye(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- void (*proc)(void *, int, godot_rid *, godot_rect2 *);
- proc = (void (*)(void *, int, godot_rid *, godot_rect2 *))library_proc;
-
- int *eye = (int *)p_args[0];
- godot_rid *rid = (godot_rid *)p_args[1];
- godot_rect2 *screen_rect = (godot_rect2 *)p_args[2];
-
- proc(p_data, *eye, rid, screen_rect);
-};
-
-void register_nativearvr_types() {
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_call_constructor", arvr_call_constructor);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_call_destructor", arvr_call_destructor);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_return_string", arvr_return_string);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_return_int", arvr_return_int);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_return_bool", arvr_return_bool);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_set_bool", arvr_set_bool);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_call_method", arvr_call_method);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_return_vector2", arvr_return_vector2);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_return_transform_for_eye", arvr_return_transform_for_eye);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_call_fill_projection_for_eye", arvr_call_fill_projection_for_eye);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("arvr_call_commit_for_eye", arvr_call_commit_for_eye);
-
- ClassDB::register_class<ARVRInterfaceGDNative>();
-}
-
-void unregister_nativearvr_types() {
-}
diff --git a/modules/gdnative/nativescript/SCsub b/modules/gdnative/nativescript/SCsub
index 178afec64a..ee3b9c351d 100644
--- a/modules/gdnative/nativescript/SCsub
+++ b/modules/gdnative/nativescript/SCsub
@@ -4,7 +4,6 @@ Import('env')
mod_env = env.Clone()
mod_env.add_source_files(env.modules_sources, "*.cpp")
-mod_env.Append(CPPPATH='#modules/gdnative')
mod_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
if "platform" in env and env["platform"] in ["x11", "iphone"]:
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 9a956ff594..63fb71feb6 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -31,7 +31,7 @@
#ifdef TOOLS_ENABLED
-#include "class_db.h"
+#include "core/class_db.h"
#include "core/global_constants.h"
#include "core/pair.h"
#include "core/project_settings.h"
diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h
index 56c2d786e6..a8e2eaf0bf 100644
--- a/modules/gdnative/nativescript/api_generator.h
+++ b/modules/gdnative/nativescript/api_generator.h
@@ -30,8 +30,8 @@
#ifndef API_GENERATOR_H
#define API_GENERATOR_H
+#include "core/typedefs.h"
#include "core/ustring.h"
-#include "typedefs.h"
Error generate_c_api(const String &p_path);
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index b9bd65af53..c1df7def2e 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -31,11 +31,11 @@
#include "gdnative/gdnative.h"
-#include "global_constants.h"
+#include "core/global_constants.h"
+#include "core/project_settings.h"
#include "io/file_access_encrypted.h"
#include "os/file_access.h"
#include "os/os.h"
-#include "project_settings.h"
#include "scene/main/scene_tree.h"
#include "scene/resources/scene_format_text.h"
@@ -137,7 +137,6 @@ bool NativeScript::can_instance() const {
#endif
}
-// TODO(karroffel): implement this
Ref<Script> NativeScript::get_base_script() const {
NativeScriptDesc *script_data = get_script_desc();
@@ -271,10 +270,6 @@ bool NativeScript::is_tool() const {
return false;
}
-String NativeScript::get_node_type() const {
- return ""; // NOTE(karroffel): uhm?
-}
-
ScriptLanguage *NativeScript::get_language() const {
return NativeScriptLanguage::get_singleton();
}
@@ -909,6 +904,9 @@ Script *NativeScriptLanguage::create_script() const {
bool NativeScriptLanguage::has_named_classes() const {
return true;
}
+bool NativeScriptLanguage::supports_builtin_mode() const {
+ return true;
+}
int NativeScriptLanguage::find_function(const String &p_function, const String &p_code) const {
return -1;
}
@@ -1010,17 +1008,15 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
if (!library_script_users.has(lib_path))
library_script_users.insert(lib_path, Set<NativeScript *>());
- void *args[1] = {
- (void *)&lib_path
- };
+ void *proc_ptr;
- // here the library registers all the classes and stuff.
- gdn->call_native_raw(_init_call_type,
- _init_call_name,
- NULL,
- 1,
- args,
- NULL);
+ Error err = gdn->get_symbol(_init_call_name, proc_ptr);
+
+ if (err != OK) {
+ ERR_PRINT(String("No " + _init_call_name + " in \"" + lib_path + "\" found").utf8().get_data());
+ } else {
+ ((void (*)(godot_string *))proc_ptr)((godot_string *)&lib_path);
+ }
} else {
// already initialized. Nice.
}
@@ -1053,13 +1049,13 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
// library_gdnatives is modified only from the main thread, so it's safe not to use mutex here
for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
if (L->get()->is_initialized()) {
- L->get()->call_native_raw(
- _noarg_call_type,
- name,
- NULL,
- 0,
- NULL,
- NULL);
+
+ void *proc_ptr;
+ Error err = L->get()->get_symbol(name, proc_ptr);
+
+ if (!err) {
+ ((void (*)())proc_ptr)();
+ }
}
}
}
@@ -1142,12 +1138,14 @@ void NativeReloadNode::_notification(int p_what) {
};
// here the library registers all the classes and stuff.
- L->get()->call_native_raw(NSL->_init_call_type,
- NSL->_init_call_name,
- NULL,
- 1,
- args,
- NULL);
+
+ void *proc_ptr;
+ Error err = L->get()->get_symbol("godot_nativescript_init", proc_ptr);
+ if (err != OK) {
+ ERR_PRINT(String("No godot_nativescript_init in \"" + L->key() + "\" found").utf8().get_data());
+ } else {
+ ((void (*)(void *))proc_ptr)((void *)&L->key());
+ }
for (Map<String, Set<NativeScript *> >::Element *U = NSL->library_script_users.front(); U; U = U->next()) {
for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index bc7e850d3e..e8fc9e6880 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -30,14 +30,14 @@
#ifndef NATIVE_SCRIPT_H
#define NATIVE_SCRIPT_H
+#include "core/resource.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "ordered_hash_map.h"
#include "os/thread_safe.h"
-#include "resource.h"
#include "scene/main/node.h"
-#include "script_language.h"
-#include "self_list.h"
#include "modules/gdnative/gdnative.h"
#include <nativescript/godot_nativescript.h>
@@ -142,8 +142,6 @@ public:
virtual bool is_tool() const;
- virtual String get_node_type() const;
-
virtual ScriptLanguage *get_language() const;
virtual bool has_script_signal(const StringName &p_signal) const;
@@ -271,6 +269,7 @@ public:
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
+ virtual bool supports_builtin_mode() const;
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index b846710ab8..d734bba810 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -38,53 +38,6 @@
NativeScriptLanguage *native_script_language;
-typedef void (*native_script_init_fn)(void *);
-
-void init_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call nativescript init procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we print our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- native_script_init_fn fn = (native_script_init_fn)library_proc;
-
- fn(args[0]);
-}
-
-typedef void (*native_script_empty_callback)();
-
-void noarg_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call nativescript callback");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true);
- if (err != OK) {
- // it's fine if thread callbacks are not present in the library.
- return;
- }
-
- native_script_empty_callback fn = (native_script_empty_callback)library_proc;
- fn();
-}
-
ResourceFormatLoaderNativeScript *resource_loader_gdns = NULL;
ResourceFormatSaverNativeScript *resource_saver_gdns = NULL;
@@ -95,9 +48,6 @@ void register_nativescript_types() {
ScriptServer::register_language(native_script_language);
- GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_init_call_type, init_call_cb);
- GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_noarg_call_type, noarg_call_cb);
-
resource_saver_gdns = memnew(ResourceFormatSaverNativeScript);
ResourceSaver::add_resource_format_saver(resource_saver_gdns);
diff --git a/modules/gdnative/pluginscript/SCsub b/modules/gdnative/pluginscript/SCsub
new file mode 100644
index 0000000000..2031a4236b
--- /dev/null
+++ b/modules/gdnative/pluginscript/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_pluginscript = env_modules.Clone()
+
+env_pluginscript.Append(CPPPATH=['#modules/gdnative/include/'])
+env_pluginscript.add_source_files(env.modules_sources, '*.cpp')
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
new file mode 100644
index 0000000000..8f01350826
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -0,0 +1,181 @@
+/*************************************************************************/
+/* pluginscript_instance.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/os.h"
+#include "core/variant.h"
+// PluginScript imports
+#include "pluginscript_instance.h"
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+
+bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) {
+ String name = String(p_name);
+ return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value);
+}
+
+bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
+ String name = String(p_name);
+ return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret);
+}
+
+Ref<Script> PluginScriptInstance::get_script() const {
+ return _script;
+}
+
+ScriptLanguage *PluginScriptInstance::get_language() {
+ return _script->get_language();
+}
+
+Variant::Type PluginScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
+ if (!_script->has_property(p_name)) {
+ if (r_is_valid) {
+ *r_is_valid = false;
+ }
+ return Variant::NIL;
+ }
+ if (r_is_valid) {
+ *r_is_valid = true;
+ }
+ return _script->get_property_info(p_name).type;
+}
+
+void PluginScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
+ _script->get_script_property_list(p_properties);
+}
+
+void PluginScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
+ _script->get_script_method_list(p_list);
+}
+
+bool PluginScriptInstance::has_method(const StringName &p_method) const {
+ return _script->has_method(p_method);
+}
+
+Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+ // TODO: optimize when calling a Godot method from Godot to avoid param conversion ?
+ godot_variant ret = _desc->call_method(
+ _data, (godot_string_name *)&p_method, (const godot_variant **)p_args,
+ p_argcount, (godot_variant_call_error *)&r_error);
+ Variant *var_ret = (Variant *)&ret;
+ return *var_ret;
+}
+
+#if 0 // TODO: Don't rely on default implementations provided by ScriptInstance ?
+void PluginScriptInstance::call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+#if 0
+ PluginScript *sptr=script.ptr();
+ Variant::CallError ce;
+
+ while(sptr) {
+ Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method);
+ if (E) {
+ E->get()->call(this,p_args,p_argcount,ce);
+ }
+ sptr = sptr->_base;
+ }
+#endif
+
+}
+
+#if 0
+void PluginScriptInstance::_ml_call_reversed(PluginScript *sptr,const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+ if (sptr->_base)
+ _ml_call_reversed(sptr->_base,p_method,p_args,p_argcount);
+
+ Variant::CallError ce;
+
+ Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method);
+ if (E) {
+ E->get()->call(this,p_args,p_argcount,ce);
+ }
+
+}
+#endif
+
+
+void PluginScriptInstance::call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+#if 0
+ if (script.ptr()) {
+ _ml_call_reversed(script.ptr(),p_method,p_args,p_argcount);
+ }
+#endif
+}
+#endif // Multilevel stuff
+
+void PluginScriptInstance::notification(int p_notification) {
+ _desc->notification(_data, p_notification);
+}
+
+ScriptInstance::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return _script->get_rpc_mode(p_method);
+}
+
+ScriptInstance::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return _script->get_rset_mode(p_variable);
+}
+
+void PluginScriptInstance::refcount_incremented() {
+ if (_desc->refcount_decremented) {
+ _desc->refcount_incremented(_data);
+ }
+}
+
+bool PluginScriptInstance::refcount_decremented() {
+ // Return true if it can die
+ if (_desc->refcount_decremented) {
+ return _desc->refcount_decremented(_data);
+ }
+ return true;
+}
+
+PluginScriptInstance::PluginScriptInstance() {
+}
+
+bool PluginScriptInstance::init(PluginScript *p_script, Object *p_owner) {
+ _owner = p_owner;
+ _owner_variant = Variant(p_owner);
+ _script = Ref<PluginScript>(p_script);
+ _desc = &p_script->_desc->instance_desc;
+ _data = _desc->init(p_script->_data, (godot_object *)p_owner);
+ ERR_FAIL_COND_V(_data == NULL, false);
+ p_owner->set_script_instance(this);
+ return true;
+}
+
+PluginScriptInstance::~PluginScriptInstance() {
+ _desc->finish(_data);
+ _script->_language->lock();
+ _script->_instances.erase(_owner);
+ _script->_language->unlock();
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
new file mode 100644
index 0000000000..68696b4417
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -0,0 +1,90 @@
+/*************************************************************************/
+/* pluginscript_instance.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_INSTANCE_H
+#define PLUGINSCRIPT_INSTANCE_H
+
+// Godot imports
+#include "core/script_language.h"
+// PluginScript imports
+#include <pluginscript/godot_pluginscript.h>
+
+class PluginScript;
+
+class PluginScriptInstance : public ScriptInstance {
+ friend class PluginScript;
+
+private:
+ Ref<PluginScript> _script;
+ Object *_owner;
+ Variant _owner_variant;
+ godot_pluginscript_instance_data *_data;
+ const godot_pluginscript_instance_desc *_desc;
+
+public:
+ _FORCE_INLINE_ Object *get_owner() { return _owner; }
+
+ virtual bool set(const StringName &p_name, const Variant &p_value);
+ virtual bool get(const StringName &p_name, Variant &r_ret) const;
+ virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+
+ 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, Variant::CallError &r_error);
+#if 0
+ // Rely on default implementations provided by ScriptInstance for the moment.
+ // Note that multilevel call could be removed in 3.0 release, so stay tunned
+ // (see https://godotengine.org/qa/9244/can-override-the-_ready-and-_process-functions-child-classes)
+ virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount);
+ virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount);
+#endif
+
+ virtual void notification(int p_notification);
+
+ virtual Ref<Script> get_script() const;
+
+ virtual ScriptLanguage *get_language();
+
+ void set_path(const String &p_path);
+
+ virtual RPCMode get_rpc_mode(const StringName &p_method) const;
+ virtual RPCMode get_rset_mode(const StringName &p_variable) const;
+
+ virtual void refcount_incremented();
+ virtual bool refcount_decremented();
+
+ PluginScriptInstance();
+ bool init(PluginScript *p_script, Object *p_owner);
+ virtual ~PluginScriptInstance();
+};
+
+#endif // PLUGINSCRIPT_INSTANCE_H
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
new file mode 100644
index 0000000000..40feb5ae43
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -0,0 +1,435 @@
+/*************************************************************************/
+/* pluginscript_language.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+// PluginScript imports
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+
+String PluginScriptLanguage::get_name() const {
+ return String(_desc.name);
+}
+
+void PluginScriptLanguage::init() {
+ _data = _desc.init();
+}
+
+String PluginScriptLanguage::get_type() const {
+ return String(_desc.type);
+}
+
+String PluginScriptLanguage::get_extension() const {
+ return String(_desc.extension);
+}
+
+Error PluginScriptLanguage::execute_file(const String &p_path) {
+ // TODO: pretty sure this method is totally deprecated and should be removed...
+ return OK;
+}
+
+void PluginScriptLanguage::finish() {
+ _desc.finish(_data);
+}
+
+/* EDITOR FUNCTIONS */
+
+void PluginScriptLanguage::get_reserved_words(List<String> *p_words) const {
+ if (_desc.reserved_words) {
+ const char **w = _desc.reserved_words;
+ while (*w) {
+ p_words->push_back(*w);
+ w++;
+ }
+ }
+}
+
+void PluginScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
+ if (_desc.comment_delimiters) {
+ const char **w = _desc.comment_delimiters;
+ while (*w) {
+ p_delimiters->push_back(*w);
+ w++;
+ }
+ }
+}
+
+void PluginScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
+ if (_desc.string_delimiters) {
+ const char **w = _desc.string_delimiters;
+ while (*w) {
+ p_delimiters->push_back(*w);
+ w++;
+ }
+ }
+}
+
+Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
+ Script *ns = create_script();
+ Ref<Script> script = Ref<Script>(ns);
+ if (_desc.get_template_source_code) {
+ godot_string src = _desc.get_template_source_code(_data, (godot_string *)&p_class_name, (godot_string *)&p_base_class_name);
+ script->set_source_code(*(String *)&src);
+ }
+ return script;
+}
+
+bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
+ PoolStringArray functions;
+ if (_desc.validate) {
+ bool ret = _desc.validate(
+ _data,
+ (godot_string *)&p_script,
+ &r_line_error,
+ &r_col_error,
+ (godot_string *)&r_test_error,
+ (godot_string *)&p_path,
+ (godot_pool_string_array *)&functions);
+ for (int i = 0; i < functions.size(); i++) {
+ r_functions->push_back(functions[i]);
+ }
+ return ret;
+ }
+ return true;
+}
+
+Script *PluginScriptLanguage::create_script() const {
+ PluginScript *script = memnew(PluginScript());
+ // I'm hurting kittens doing this I guess...
+ script->init(const_cast<PluginScriptLanguage *>(this));
+ return script;
+}
+
+bool PluginScriptLanguage::has_named_classes() const {
+ return _desc.has_named_classes;
+}
+
+bool PluginScriptLanguage::supports_builtin_mode() const {
+ return _desc.supports_builtin_mode;
+}
+
+int PluginScriptLanguage::find_function(const String &p_function, const String &p_code) const {
+ if (_desc.find_function) {
+ return _desc.find_function(_data, (godot_string *)&p_function, (godot_string *)&p_code);
+ }
+ return -1;
+}
+
+String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+ if (_desc.make_function) {
+ godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_pool_string_array *)&p_args);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String();
+}
+
+Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) {
+ if (_desc.complete_code) {
+ Array options;
+ godot_error tmp = _desc.complete_code(
+ _data,
+ (godot_string *)&p_code,
+ (godot_string *)&p_base_path,
+ (godot_object *)p_owner,
+ (godot_array *)&options,
+ &r_force,
+ (godot_string *)&r_call_hint);
+ for (int i = 0; i < options.size(); i++) {
+ r_options->push_back(String(options[i]));
+ }
+ Error err = *(Error *)tmp;
+ return err;
+ }
+ return ERR_UNAVAILABLE;
+}
+
+void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
+ if (_desc.auto_indent_code) {
+ _desc.auto_indent_code(_data, (godot_string *)&p_code, p_from_line, p_to_line);
+ }
+ return;
+}
+
+void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
+ const String variable = String(p_variable);
+ _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value);
+}
+
+/* LOADER FUNCTIONS */
+
+void PluginScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
+ for (int i = 0; _desc.recognized_extensions[i]; ++i) {
+ p_extensions->push_back(String(_desc.recognized_extensions[i]));
+ }
+}
+
+void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
+ // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ if (_desc.get_public_functions) {
+ Array functions;
+ _desc.get_public_functions(_data, (godot_array *)&functions);
+ for (int i = 0; i < functions.size(); i++) {
+ MethodInfo mi = MethodInfo::from_dict(functions[i]);
+ p_functions->push_back(mi);
+ }
+ }
+}
+
+void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+ // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ if (_desc.get_public_constants) {
+ Dictionary constants;
+ _desc.get_public_constants(_data, (godot_dictionary *)&constants);
+ for (const Variant *key = constants.next(); key; key = constants.next(key)) {
+ Variant value = constants[key];
+ p_constants->push_back(Pair<String, Variant>(*key, value));
+ }
+ }
+}
+
+void PluginScriptLanguage::profiling_start() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_start) {
+ lock();
+ _desc.profiling_start(_data);
+ unlock();
+ }
+#endif
+}
+
+void PluginScriptLanguage::profiling_stop() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_stop) {
+ lock();
+ _desc.profiling_stop(_data);
+ unlock();
+ }
+#endif
+}
+
+int PluginScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ int info_count = 0;
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_get_accumulated_data) {
+ godot_pluginscript_profiling_data *info = (godot_pluginscript_profiling_data *)memalloc(
+ sizeof(godot_pluginscript_profiling_data) * p_info_max);
+ info_count = _desc.profiling_get_accumulated_data(_data, info, p_info_max);
+ for (int i = 0; i < info_count; ++i) {
+ p_info_arr[i].signature = *(StringName *)&info[i].signature;
+ p_info_arr[i].call_count = info[i].call_count;
+ p_info_arr[i].total_time = info[i].total_time;
+ p_info_arr[i].self_time = info[i].self_time;
+ godot_string_name_destroy(&info[i].signature);
+ }
+ }
+#endif
+ return info_count;
+}
+
+int PluginScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ int info_count = 0;
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_get_frame_data) {
+ godot_pluginscript_profiling_data *info = (godot_pluginscript_profiling_data *)memalloc(
+ sizeof(godot_pluginscript_profiling_data) * p_info_max);
+ info_count = _desc.profiling_get_frame_data(_data, info, p_info_max);
+ for (int i = 0; i < info_count; ++i) {
+ p_info_arr[i].signature = *(StringName *)&info[i].signature;
+ p_info_arr[i].call_count = info[i].call_count;
+ p_info_arr[i].total_time = info[i].total_time;
+ p_info_arr[i].self_time = info[i].self_time;
+ godot_string_name_destroy(&info[i].signature);
+ }
+ }
+#endif
+ return info_count;
+}
+
+void PluginScriptLanguage::frame() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_frame) {
+ _desc.profiling_frame(_data);
+ }
+#endif
+}
+
+/* DEBUGGER FUNCTIONS */
+
+String PluginScriptLanguage::debug_get_error() const {
+ if (_desc.debug_get_error) {
+ godot_string tmp = _desc.debug_get_error(_data);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+int PluginScriptLanguage::debug_get_stack_level_count() const {
+ if (_desc.debug_get_stack_level_count) {
+ return _desc.debug_get_stack_level_count(_data);
+ }
+ return 1;
+}
+
+int PluginScriptLanguage::debug_get_stack_level_line(int p_level) const {
+ if (_desc.debug_get_stack_level_line) {
+ return _desc.debug_get_stack_level_line(_data, p_level);
+ }
+ return 1;
+}
+
+String PluginScriptLanguage::debug_get_stack_level_function(int p_level) const {
+ if (_desc.debug_get_stack_level_function) {
+ godot_string tmp = _desc.debug_get_stack_level_function(_data, p_level);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+String PluginScriptLanguage::debug_get_stack_level_source(int p_level) const {
+ if (_desc.debug_get_stack_level_source) {
+ godot_string tmp = _desc.debug_get_stack_level_source(_data, p_level);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_stack_level_locals) {
+ PoolStringArray locals;
+ Array values;
+ _desc.debug_get_stack_level_locals(_data, p_level, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < locals.size(); i++) {
+ p_locals->push_back(locals[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_stack_level_members) {
+ PoolStringArray members;
+ Array values;
+ _desc.debug_get_stack_level_members(_data, p_level, (godot_pool_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < members.size(); i++) {
+ p_members->push_back(members[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+void PluginScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_globals) {
+ PoolStringArray locals;
+ Array values;
+ _desc.debug_get_globals(_data, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < locals.size(); i++) {
+ p_locals->push_back(locals[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+String PluginScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_parse_stack_level_expression) {
+ godot_string tmp = _desc.debug_parse_stack_level_expression(_data, p_level, (godot_string *)&p_expression, p_max_subitems, p_max_depth);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+void PluginScriptLanguage::reload_all_scripts() {
+ // TODO
+}
+
+void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
+#ifdef DEBUG_ENABLED
+ lock();
+ // TODO
+ unlock();
+#endif
+}
+
+void PluginScriptLanguage::lock() {
+#ifndef NO_THREADS
+ if (_lock) {
+ _lock->lock();
+ }
+#endif
+}
+
+void PluginScriptLanguage::unlock() {
+#ifndef NO_THREADS
+ if (_lock) {
+ _lock->unlock();
+ }
+#endif
+}
+
+PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc)
+ : _desc(*desc) {
+ _resource_loader = memnew(ResourceFormatLoaderPluginScript(this));
+ _resource_saver = memnew(ResourceFormatSaverPluginScript(this));
+
+// TODO: totally remove _lock attribute if NO_THREADS is set
+#ifdef NO_THREADS
+ _lock = NULL;
+#else
+ _lock = Mutex::create();
+#endif
+}
+
+PluginScriptLanguage::~PluginScriptLanguage() {
+ memdelete(_resource_loader);
+ memdelete(_resource_saver);
+#ifndef NO_THREADS
+ if (_lock) {
+ memdelete(_lock);
+ _lock = NULL;
+ }
+#endif
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
new file mode 100644
index 0000000000..79b95ff4e6
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -0,0 +1,132 @@
+/*************************************************************************/
+/* pluginscript_language.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_LANGUAGE_H
+#define PLUGINSCRIPT_LANGUAGE_H
+
+// Godot imports
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/map.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
+// PluginScript imports
+#include "pluginscript_loader.h"
+#include <pluginscript/godot_pluginscript.h>
+
+class PluginScript;
+class PluginScriptInstance;
+
+class PluginScriptLanguage : public ScriptLanguage {
+ friend class PluginScript;
+ friend class PluginScriptInstance;
+
+ ResourceFormatLoaderPluginScript *_resource_loader;
+ ResourceFormatSaverPluginScript *_resource_saver;
+ const godot_pluginscript_language_desc _desc;
+ godot_pluginscript_language_data *_data;
+
+ Mutex *_lock;
+ SelfList<PluginScript>::List _script_list;
+
+public:
+ virtual String get_name() const;
+
+ _FORCE_INLINE_ ResourceFormatLoaderPluginScript *get_resource_loader() { return _resource_loader; };
+ _FORCE_INLINE_ ResourceFormatSaverPluginScript *get_resource_saver() { return _resource_saver; };
+
+ /* LANGUAGE FUNCTIONS */
+ virtual void init();
+ virtual String get_type() const;
+ virtual String get_extension() const;
+ virtual Error execute_file(const String &p_path);
+ virtual void finish();
+
+ /* EDITOR FUNCTIONS */
+ virtual void get_reserved_words(List<String> *p_words) const;
+ virtual void get_comment_delimiters(List<String> *p_delimiters) const;
+ virtual void get_string_delimiters(List<String> *p_delimiters) const;
+ virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
+ virtual Script *create_script() const;
+ virtual bool has_named_classes() const;
+ virtual bool supports_builtin_mode() const;
+ virtual bool can_inherit_from_file() { return true; }
+ virtual int find_function(const String &p_function, const String &p_code) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint);
+ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
+ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
+
+ /* MULTITHREAD FUNCTIONS */
+
+ //some VMs need to be notified of thread creation/exiting to allocate a stack
+ // void thread_enter() {}
+ // void thread_exit() {}
+
+ /* DEBUGGER FUNCTIONS */
+
+ virtual String debug_get_error() const;
+ virtual int debug_get_stack_level_count() const;
+ virtual int debug_get_stack_level_line(int p_level) const;
+ virtual String debug_get_stack_level_function(int p_level) const;
+ virtual String debug_get_stack_level_source(int p_level) const;
+ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1);
+
+ // virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
+
+ virtual void reload_all_scripts();
+ virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
+
+ /* LOADER FUNCTIONS */
+
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual void get_public_functions(List<MethodInfo> *p_functions) const;
+ virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+
+ virtual void profiling_start();
+ virtual void profiling_stop();
+
+ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max);
+ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max);
+
+ virtual void frame();
+
+ void lock();
+ void unlock();
+
+ PluginScriptLanguage(const godot_pluginscript_language_desc *desc);
+ virtual ~PluginScriptLanguage();
+};
+
+#endif // PLUGINSCRIPT_LANGUAGE_H
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
new file mode 100644
index 0000000000..3648e1a5b4
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -0,0 +1,113 @@
+/*************************************************************************/
+/* pluginscript_loader.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "os/file_access.h"
+// Pythonscript imports
+#include "pluginscript_language.h"
+#include "pluginscript_loader.h"
+#include "pluginscript_script.h"
+
+ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptLanguage *language) {
+ _language = language;
+}
+
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+ if (r_error)
+ *r_error = ERR_FILE_CANT_OPEN;
+
+ PluginScript *script = memnew(PluginScript);
+ script->init(_language);
+
+ Ref<PluginScript> scriptres(script);
+
+ Error err = script->load_source_code(p_path);
+ ERR_FAIL_COND_V(err != OK, RES());
+
+ script->set_path(p_original_path);
+
+ script->reload();
+
+ if (r_error)
+ *r_error = OK;
+
+ return scriptres;
+}
+
+void ResourceFormatLoaderPluginScript::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back(_language->get_extension());
+}
+
+bool ResourceFormatLoaderPluginScript::handles_type(const String &p_type) const {
+ return p_type == "Script" || p_type == _language->get_type();
+}
+
+String ResourceFormatLoaderPluginScript::get_resource_type(const String &p_path) const {
+ String el = p_path.get_extension().to_lower();
+ if (el == _language->get_extension())
+ return _language->get_type();
+ return "";
+}
+
+ResourceFormatSaverPluginScript::ResourceFormatSaverPluginScript(PluginScriptLanguage *language) {
+ _language = language;
+}
+
+Error ResourceFormatSaverPluginScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+ Ref<PluginScript> sqscr = p_resource;
+ ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
+
+ String source = sqscr->get_source_code();
+
+ Error err;
+ FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ ERR_FAIL_COND_V(err, err);
+
+ file->store_string(source);
+ if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
+ memdelete(file);
+ return ERR_CANT_CREATE;
+ }
+ file->close();
+ memdelete(file);
+ return OK;
+}
+
+void ResourceFormatSaverPluginScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+
+ if (Object::cast_to<PluginScript>(*p_resource)) {
+ p_extensions->push_back(_language->get_extension());
+ }
+}
+
+bool ResourceFormatSaverPluginScript::recognize(const RES &p_resource) const {
+
+ return Object::cast_to<PluginScript>(*p_resource) != NULL;
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
new file mode 100644
index 0000000000..b85e7725a1
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* pluginscript_loader.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PYTHONSCRIPT_PY_LOADER_H
+#define PYTHONSCRIPT_PY_LOADER_H
+
+// Godot imports
+#include "core/script_language.h"
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+
+class PluginScriptLanguage;
+
+class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
+ PluginScriptLanguage *_language;
+
+public:
+ ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverPluginScript : public ResourceFormatSaver {
+ PluginScriptLanguage *_language;
+
+public:
+ ResourceFormatSaverPluginScript(PluginScriptLanguage *language);
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+ virtual bool recognize(const RES &p_resource) const;
+};
+
+#endif // PYTHONSCRIPT_PY_LOADER_H
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
new file mode 100644
index 0000000000..4169b07f63
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -0,0 +1,449 @@
+/*************************************************************************/
+/* pluginscript_script.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/file_access.h"
+// PluginScript imports
+#include "pluginscript_instance.h"
+#include "pluginscript_script.h"
+
+#if DEBUG_ENABLED
+#define __ASSERT_SCRIPT_REASON "Cannot retrieve pluginscript class for this script, is you code correct ?"
+#define ASSERT_SCRIPT_VALID() \
+ { \
+ ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
+ ERR_FAIL_COND(!can_instance()) \
+ }
+#define ASSERT_SCRIPT_VALID_V(ret) \
+ { \
+ ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
+ ERR_FAIL_COND_V(!can_instance(), ret) \
+ }
+#else
+#define ASSERT_SCRIPT_VALID()
+#define ASSERT_SCRIPT_VALID_V(ret)
+#endif
+
+void PluginScript::_bind_methods() {
+}
+
+#ifdef TOOLS_ENABLED
+
+void PluginScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
+ placeholders.erase(p_placeholder);
+}
+
+#endif
+
+bool PluginScript::can_instance() const {
+ bool can = _valid || (!_tool && !ScriptServer::is_scripting_enabled());
+ return can;
+}
+
+Ref<Script> PluginScript::get_base_script() const {
+ if (_ref_base_parent.is_valid()) {
+ return Ref<PluginScript>(_ref_base_parent);
+ } else {
+ return Ref<Script>();
+ }
+}
+
+StringName PluginScript::get_instance_base_type() const {
+ if (_native_parent)
+ return _native_parent;
+ if (_ref_base_parent.is_valid())
+ return _ref_base_parent->get_instance_base_type();
+ return StringName();
+}
+
+void PluginScript::update_exports() {
+// TODO
+#ifdef TOOLS_ENABLED
+#if 0
+ ASSERT_SCRIPT_VALID();
+ if (/*changed &&*/ placeholders.size()) { //hm :(
+
+ //update placeholders if any
+ Map<StringName, Variant> propdefvalues;
+ List<PropertyInfo> propinfos;
+ const String *props = (const String *)pybind_get_prop_list(_py_exposed_class);
+ for (int i = 0; props[i] != ""; ++i) {
+ const String propname = props[i];
+ pybind_get_prop_default_value(_py_exposed_class, propname.c_str(), (godot_variant *)&propdefvalues[propname]);
+ pybind_prop_info raw_info;
+ pybind_get_prop_info(_py_exposed_class, propname.c_str(), &raw_info);
+ PropertyInfo info;
+ info.type = (Variant::Type)raw_info.type;
+ info.name = propname;
+ info.hint = (PropertyHint)raw_info.hint;
+ info.hint_string = *(String *)&raw_info.hint_string;
+ info.usage = raw_info.usage;
+ propinfos.push_back(info);
+ }
+ for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->update(propinfos, propdefvalues);
+ }
+ }
+#endif
+#endif
+}
+
+// TODO: rename p_this "p_owner" ?
+ScriptInstance *PluginScript::instance_create(Object *p_this) {
+ ASSERT_SCRIPT_VALID_V(NULL);
+ // TODO check script validity ?
+ if (!_tool && !ScriptServer::is_scripting_enabled()) {
+#ifdef TOOLS_ENABLED
+ // Instance a fake script for editing the values
+ PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(get_language(), Ref<Script>(this), p_this));
+ placeholders.insert(si);
+ update_exports();
+ return si;
+#else
+ return NULL;
+#endif
+ }
+
+ PluginScript *top = this;
+ // TODO: can be optimized by storing a PluginScript::_base_parent direct pointer
+ while (top->_ref_base_parent.is_valid())
+ top = top->_ref_base_parent.ptr();
+ if (top->_native_parent) {
+ if (!ClassDB::is_parent_class(p_this->get_class_name(), top->_native_parent)) {
+ String msg = "Script inherits from native type '" + String(top->_native_parent) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'";
+ // TODO: implement PluginscriptLanguage::debug_break_parse
+ // if (ScriptDebugger::get_singleton()) {
+ // _language->debug_break_parse(get_path(), 0, msg);
+ // }
+ ERR_EXPLAIN(msg);
+ ERR_FAIL_V(NULL);
+ }
+ }
+
+ PluginScriptInstance *instance = memnew(PluginScriptInstance());
+ const bool success = instance->init(this, p_this);
+ if (success) {
+ _language->lock();
+ _instances.insert(instance->get_owner());
+ _language->unlock();
+ return instance;
+ } else {
+ memdelete(instance);
+ ERR_FAIL_V(NULL);
+ }
+}
+
+bool PluginScript::instance_has(const Object *p_this) const {
+ _language->lock();
+ bool hasit = _instances.has((Object *)p_this);
+ _language->unlock();
+ return hasit;
+}
+
+bool PluginScript::has_source_code() const {
+ bool has = _source != "";
+ return has;
+}
+
+String PluginScript::get_source_code() const {
+ return _source;
+}
+
+void PluginScript::set_source_code(const String &p_code) {
+ if (_source == p_code)
+ return;
+ _source = p_code;
+}
+
+Error PluginScript::reload(bool p_keep_state) {
+ _language->lock();
+ ERR_FAIL_COND_V(!p_keep_state && _instances.size(), ERR_ALREADY_IN_USE);
+ _language->unlock();
+
+ _valid = false;
+ String basedir = _path;
+
+ if (basedir == "")
+ basedir = get_path();
+
+ if (basedir != "")
+ basedir = basedir.get_base_dir();
+
+ if (_data) {
+ _desc->finish(_data);
+ }
+
+ Error err;
+ godot_pluginscript_script_manifest manifest = _desc->init(
+ _language->_data,
+ (godot_string *)&_path,
+ (godot_string *)&_source,
+ (godot_error *)&err);
+ if (err) {
+ // TODO: GDscript uses `ScriptDebugger` here to jump into the parsing error
+ return err;
+ }
+ _valid = true;
+ // Use the manifest to configure this script object
+ _data = manifest.data;
+ _name = *(StringName *)&manifest.name;
+ _tool = manifest.is_tool;
+ // Base name is either another PluginScript or a regular class accessible
+ // through ClassDB
+ StringName *base_name = (StringName *)&manifest.base;
+ for (SelfList<PluginScript> *e = _language->_script_list.first(); e != NULL; e = e->next()) {
+ if (e->self()->_name == *base_name) {
+ // Found you, base is a PluginScript !
+ _ref_base_parent = Ref<PluginScript>(e->self());
+ break;
+ }
+ }
+ if (!_ref_base_parent.is_valid()) {
+ // Base is a native ClassDB
+ if (!ClassDB::class_exists(*base_name)) {
+ ERR_EXPLAIN("Unknown script '" + String(_name) + "' parent '" + String(*base_name) + "'.");
+ ERR_FAIL_V(ERR_PARSE_ERROR);
+ }
+ _native_parent = *base_name;
+ }
+
+ Dictionary *members = (Dictionary *)&manifest.member_lines;
+ for (const Variant *key = members->next(); key != NULL; key = members->next(key)) {
+ _member_lines[*key] = (*members)[key];
+ }
+ Array *methods = (Array *)&manifest.methods;
+ for (int i = 0; i < methods->size(); ++i) {
+ Dictionary v = (*methods)[i];
+ MethodInfo mi = MethodInfo::from_dict(v);
+ _methods_info[mi.name] = mi;
+ // rpc_mode is passed as an optional field and is not part of MethodInfo
+ Variant var = v["rpc_mode"];
+ if (var == Variant()) {
+ _methods_rpc_mode[mi.name] = ScriptInstance::RPC_MODE_DISABLED;
+ } else {
+ _methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var));
+ }
+ }
+ Array *signals = (Array *)&manifest.signals;
+ for (int i = 0; i < signals->size(); ++i) {
+ Variant v = (*signals)[i];
+ MethodInfo mi = MethodInfo::from_dict(v);
+ _signals_info[mi.name] = mi;
+ }
+ Array *properties = (Array *)&manifest.properties;
+ for (int i = 0; i < properties->size(); ++i) {
+ Dictionary v = (*properties)[i];
+ PropertyInfo pi = PropertyInfo::from_dict(v);
+ _properties_info[pi.name] = pi;
+ _properties_default_values[pi.name] = v["default_value"];
+ // rset_mode is passed as an optional field and is not part of PropertyInfo
+ Variant var = v["rset_mode"];
+ if (var == Variant()) {
+ _methods_rpc_mode[pi.name] = ScriptInstance::RPC_MODE_DISABLED;
+ } else {
+ _methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var));
+ }
+ }
+ // Manifest's attributes must be explicitly freed
+ godot_string_name_destroy(&manifest.name);
+ godot_string_name_destroy(&manifest.base);
+ godot_dictionary_destroy(&manifest.member_lines);
+ godot_array_destroy(&manifest.methods);
+ godot_array_destroy(&manifest.signals);
+ godot_array_destroy(&manifest.properties);
+
+#ifdef TOOLS_ENABLED
+/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
+
+ _update_placeholder(E->get());
+ }*/
+#endif
+ return OK;
+}
+
+void PluginScript::get_script_method_list(List<MethodInfo> *r_methods) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != NULL; e = e->next()) {
+ r_methods->push_back(e->get());
+ }
+}
+
+void PluginScript::get_script_property_list(List<PropertyInfo> *r_properties) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != NULL; e = e->next()) {
+ r_properties->push_back(e->get());
+ }
+}
+
+bool PluginScript::has_method(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _methods_info.has(p_method);
+}
+
+MethodInfo PluginScript::get_method_info(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(MethodInfo());
+ const Map<StringName, MethodInfo>::Element *e = _methods_info.find(p_method);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return MethodInfo();
+ }
+}
+
+bool PluginScript::has_property(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _properties_info.has(p_method);
+}
+
+PropertyInfo PluginScript::get_property_info(const StringName &p_property) const {
+ ASSERT_SCRIPT_VALID_V(PropertyInfo());
+ const Map<StringName, PropertyInfo>::Element *e = _properties_info.find(p_property);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return PropertyInfo();
+ }
+}
+
+bool PluginScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
+ ASSERT_SCRIPT_VALID_V(false);
+#ifdef TOOLS_ENABLED
+ const Map<StringName, Variant>::Element *e = _properties_default_values.find(p_property);
+ if (e != NULL) {
+ r_value = e->get();
+ return true;
+ } else {
+ return false;
+ }
+#endif
+ return false;
+}
+
+ScriptLanguage *PluginScript::get_language() const {
+ return _language;
+}
+
+Error PluginScript::load_source_code(const String &p_path) {
+
+ PoolVector<uint8_t> sourcef;
+ Error err;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ if (err) {
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ int len = f->get_len();
+ sourcef.resize(len + 1);
+ PoolVector<uint8_t>::Write w = sourcef.write();
+ int r = f->get_buffer(w.ptr(), len);
+ f->close();
+ memdelete(f);
+ ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
+ w[len] = 0;
+
+ String s;
+ if (s.parse_utf8((const char *)w.ptr())) {
+ ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
+ ERR_FAIL_V(ERR_INVALID_DATA);
+ }
+
+ _source = s;
+#ifdef TOOLS_ENABLED
+// source_changed_cache=true;
+#endif
+ _path = p_path;
+ return OK;
+}
+
+bool PluginScript::has_script_signal(const StringName &p_signal) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _signals_info.has(p_signal);
+}
+
+void PluginScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != NULL; e = e->next()) {
+ r_signals->push_back(e->get());
+ }
+}
+
+int PluginScript::get_member_line(const StringName &p_member) const {
+#ifdef TOOLS_ENABLED
+ if (_member_lines.has(p_member))
+ return _member_lines[p_member];
+ else
+#endif
+ return -1;
+}
+
+ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
+ const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return ScriptInstance::RPC_MODE_DISABLED;
+ }
+}
+
+ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+ ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
+ const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return ScriptInstance::RPC_MODE_DISABLED;
+ }
+}
+
+PluginScript::PluginScript()
+ : _data(NULL), _tool(false), _valid(false), _script_list(this) {
+}
+
+void PluginScript::init(PluginScriptLanguage *language) {
+ _desc = &language->_desc.script_desc;
+ _language = language;
+
+#ifdef DEBUG_ENABLED
+ _language->lock();
+ _language->_script_list.add(&_script_list);
+ _language->unlock();
+#endif
+}
+
+PluginScript::~PluginScript() {
+ _desc->finish(_data);
+
+#ifdef DEBUG_ENABLED
+ _language->lock();
+ _language->_script_list.remove(&_script_list);
+ _language->unlock();
+#endif
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
new file mode 100644
index 0000000000..5600bca5ef
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -0,0 +1,127 @@
+/*************************************************************************/
+/* pluginscript_script.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_SCRIPT_H
+#define PLUGINSCRIPT_SCRIPT_H
+
+// Godot imports
+#include "core/script_language.h"
+// PluginScript imports
+#include "pluginscript_language.h"
+#include <pluginscript/godot_pluginscript.h>
+
+class PyInstance;
+
+class PluginScript : public Script {
+
+ GDCLASS(PluginScript, Script);
+
+ friend class PluginScriptInstance;
+ friend class PluginScriptLanguage;
+
+private:
+ godot_pluginscript_script_data *_data;
+ const godot_pluginscript_script_desc *_desc;
+ PluginScriptLanguage *_language;
+ bool _tool;
+ bool _valid;
+
+ Ref<PluginScript> _ref_base_parent;
+ StringName _native_parent;
+ SelfList<PluginScript> _script_list;
+
+ Map<StringName, int> _member_lines;
+ Map<StringName, Variant> _properties_default_values;
+ Map<StringName, PropertyInfo> _properties_info;
+ Map<StringName, MethodInfo> _signals_info;
+ Map<StringName, MethodInfo> _methods_info;
+ Map<StringName, ScriptInstance::RPCMode> _variables_rset_mode;
+ Map<StringName, ScriptInstance::RPCMode> _methods_rpc_mode;
+
+ Set<Object *> _instances;
+ //exported members
+ String _source;
+ String _path;
+ StringName _name;
+
+protected:
+ static void _bind_methods();
+
+#ifdef TOOLS_ENABLED
+ Set<PlaceHolderScriptInstance *> placeholders;
+ //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
+ virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
+#endif
+public:
+ virtual bool can_instance() const;
+
+ virtual Ref<Script> get_base_script() const; //for script inheritance
+
+ virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so
+ virtual ScriptInstance *instance_create(Object *p_this);
+ virtual bool instance_has(const Object *p_this) const;
+
+ virtual bool has_source_code() const;
+ virtual String get_source_code() const;
+ virtual void set_source_code(const String &p_code);
+ virtual Error reload(bool p_keep_state = false);
+ // TODO: load_source_code only allow utf-8 file, should handle bytecode as well ?
+ virtual Error load_source_code(const String &p_path);
+
+ virtual bool has_method(const StringName &p_method) const;
+ virtual MethodInfo get_method_info(const StringName &p_method) const;
+
+ bool has_property(const StringName &p_method) const;
+ PropertyInfo get_property_info(const StringName &p_property) const;
+
+ bool is_tool() const { return _tool; }
+
+ virtual ScriptLanguage *get_language() const;
+
+ virtual bool has_script_signal(const StringName &p_signal) const;
+ virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
+
+ virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const;
+
+ virtual void update_exports();
+ virtual void get_script_method_list(List<MethodInfo> *r_methods) const;
+ virtual void get_script_property_list(List<PropertyInfo> *r_propertieslist) const;
+
+ virtual int get_member_line(const StringName &p_member) const;
+
+ ScriptInstance::RPCMode get_rpc_mode(const StringName &p_method) const;
+ ScriptInstance::RPCMode get_rset_mode(const StringName &p_variable) const;
+
+ PluginScript();
+ void init(PluginScriptLanguage *language);
+ virtual ~PluginScript();
+};
+
+#endif // PLUGINSCRIPT_SCRIPT_H
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
new file mode 100644
index 0000000000..5829d08dff
--- /dev/null
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -0,0 +1,118 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 "core/project_settings.h"
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+#include "os/dir_access.h"
+#include "os/os.h"
+#include "scene/main/scene_tree.h"
+
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+#include <pluginscript/godot_pluginscript.h>
+
+static List<PluginScriptLanguage *> pluginscript_languages;
+
+static Error _check_language_desc(const godot_pluginscript_language_desc *desc) {
+ ERR_FAIL_COND_V(!desc->name || desc->name == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->type || desc->type == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->extension || desc->extension == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->recognized_extensions || !desc->recognized_extensions[0], ERR_BUG);
+ ERR_FAIL_COND_V(!desc->init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->finish, ERR_BUG);
+
+ // desc->reserved_words is not mandatory
+ // desc->comment_delimiters is not mandatory
+ // desc->string_delimiters is not mandatory
+
+ // desc->get_template_source_code is not mandatory
+ // desc->validate is not mandatory
+
+ // desc->get_template_source_code is not mandatory
+ // desc->validate is not mandatory
+ // desc->find_function is not mandatory
+ // desc->make_function is not mandatory
+ // desc->complete_code is not mandatory
+ // desc->auto_indent_code is not mandatory
+ // desc->add_global_constant is not mandatory
+ // desc->debug_get_error is not mandatory
+ // desc->debug_get_stack_level_count is not mandatory
+ // desc->debug_get_stack_level_line is not mandatory
+ // desc->debug_get_stack_level_function is not mandatory
+ // desc->debug_get_stack_level_source is not mandatory
+ // desc->debug_get_stack_level_locals is not mandatory
+ // desc->debug_get_stack_level_members is not mandatory
+ // desc->debug_get_globals is not mandatory
+ // desc->debug_parse_stack_level_expression is not mandatory
+ // desc->profiling_start is not mandatory
+ // desc->profiling_stop is not mandatory
+ // desc->profiling_get_accumulated_data is not mandatory
+ // desc->profiling_get_frame_data is not mandatory
+ // desc->frame is not mandatory
+
+ ERR_FAIL_COND_V(!desc->script_desc.init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.finish, ERR_BUG);
+
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.finish, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.set_prop, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.get_prop, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.call_method, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.notification, ERR_BUG);
+ // desc->script_desc.instance_desc.refcount_incremented is not mandatory
+ // desc->script_desc.instance_desc.refcount_decremented is not mandatory
+ return OK;
+}
+
+void GDAPI godot_pluginscript_register_language(const godot_pluginscript_language_desc *language_desc) {
+ Error ret = _check_language_desc(language_desc);
+ if (ret) {
+ ERR_FAIL();
+ }
+ PluginScriptLanguage *language = memnew(PluginScriptLanguage(language_desc));
+ ScriptServer::register_language(language);
+ ResourceLoader::add_resource_format_loader(language->get_resource_loader());
+ ResourceSaver::add_resource_format_saver(language->get_resource_saver());
+ pluginscript_languages.push_back(language);
+}
+
+void register_pluginscript_types() {
+ ClassDB::register_class<PluginScript>();
+}
+
+void unregister_pluginscript_types() {
+ for (List<PluginScriptLanguage *>::Element *e = pluginscript_languages.front(); e; e = e->next()) {
+ PluginScriptLanguage *language = e->get();
+ ScriptServer::unregister_language(language);
+ memdelete(language);
+ }
+}
diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h
new file mode 100644
index 0000000000..70bbb16c62
--- /dev/null
+++ b/modules/gdnative/pluginscript/register_types.h
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* register_types.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+void register_pluginscript_types();
+void unregister_pluginscript_types();
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 8f4eed091f..19a62b9c4f 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -35,8 +35,9 @@
#include "io/resource_loader.h"
#include "io/resource_saver.h"
-#include "nativearvr/register_types.h"
+#include "arvr/register_types.h"
#include "nativescript/register_types.h"
+#include "pluginscript/register_types.h"
#include "core/engine.h"
#include "core/os/os.h"
@@ -128,57 +129,12 @@ static void editor_init_callback() {
#endif
-godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot_array *p_args) {
- if (handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- godot_variant ret;
- godot_variant_new_nil(&ret);
- return ret;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- handle,
- *(String *)p_procedure,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_procedure) + "\" does not exists and can't be called").utf8().get_data());
- godot_variant ret;
- godot_variant_new_nil(&ret);
- return ret;
- }
+godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *p_args) {
godot_gdnative_procedure_fn proc;
- proc = (godot_gdnative_procedure_fn)library_proc;
+ proc = (godot_gdnative_procedure_fn)p_procedure_handle;
- return proc(NULL, p_args);
-}
-
-void cb_singleton_call(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call singleton procedure");
- return;
- }
-
- void *singleton_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- singleton_proc);
-
- if (err != OK) {
- return;
- }
-
- void (*singleton_procedure_ptr)() = (void (*)())singleton_proc;
- singleton_procedure_ptr();
+ return proc(p_args);
}
GDNativeCallRegistry *GDNativeCallRegistry::singleton;
@@ -201,14 +157,16 @@ void register_gdnative_types() {
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("gdnative_singleton_call", cb_singleton_call);
-
- register_nativearvr_types();
+ register_arvr_types();
register_nativescript_types();
+ register_pluginscript_types();
// run singletons
- Array singletons = ProjectSettings::get_singleton()->get("gdnative/singletons");
+ Array singletons = Array();
+ if (ProjectSettings::get_singleton()->has_setting("gdnative/singletons")) {
+ singletons = ProjectSettings::get_singleton()->get("gdnative/singletons");
+ }
singleton_gdnatives.resize(singletons.size());
@@ -225,13 +183,16 @@ void register_gdnative_types() {
continue;
}
- singleton_gdnatives[i]->call_native_raw(
- "gdnative_singleton_call",
+ void *proc_ptr;
+ Error err = singleton_gdnatives[i]->get_symbol(
"godot_gdnative_singleton",
- NULL,
- 0,
- NULL,
- NULL);
+ proc_ptr);
+
+ if (err != OK) {
+ ERR_PRINT((String("No godot_gdnative_singleton in \"" + singleton_gdnatives[i]->get_library()->get_active_library_path()) + "\" found").utf8().get_data());
+ } else {
+ ((void (*)())proc_ptr)();
+ }
}
}
@@ -251,8 +212,9 @@ void unregister_gdnative_types() {
}
singleton_gdnatives.clear();
- unregister_nativearvr_types();
+ unregister_pluginscript_types();
unregister_nativescript_types();
+ unregister_arvr_types();
memdelete(GDNativeCallRegistry::singleton);
@@ -283,4 +245,4 @@ void unregister_gdnative_types() {
print_line(String("vector2:\t") + itos(sizeof(Vector2)));
print_line(String("vector3:\t") + itos(sizeof(Vector3)));
*/
-} \ No newline at end of file
+}
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index b0408917a4..346b7d326a 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -61,7 +61,11 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
"func _ready():\n" +
"%TS%# Called every time the node is added to the scene.\n" +
"%TS%# Initialization here\n" +
- "%TS%pass\n";
+ "%TS%pass\n\n" +
+ "#func _process(delta):\n" +
+ "#%TS%# Called every frame. Delta is time since last frame.\n" +
+ "#%TS%# Update game logic here.\n" +
+ "#%TS%pass\n";
_template = _template.replace("%BASE%", p_base_class_name);
_template = _template.replace("%TS%", _get_indentation());
@@ -127,6 +131,11 @@ bool GDScriptLanguage::has_named_classes() const {
return false;
}
+bool GDScriptLanguage::supports_builtin_mode() const {
+
+ return true;
+}
+
int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const {
GDTokenizerText tokenizer;
@@ -328,6 +337,11 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_cons
pi.second = Math_PI;
p_constants->push_back(pi);
+ Pair<String, Variant> tau;
+ tau.first = "TAU";
+ tau.second = Math_TAU;
+ p_constants->push_back(tau);
+
Pair<String, Variant> infinity;
infinity.first = "INF";
infinity.second = Math_INF;
@@ -1051,7 +1065,7 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_
}
//use the last assignment, (then backwards?)
- if (last_assign) {
+ if (last_assign && last_assign_line != p_line) {
return _guess_expression_type(context, last_assign, last_assign_line, r_type);
}
@@ -1185,6 +1199,8 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con
r_type = _get_type_from_pinfo(context._class->variables[i]._export);
return true;
} else if (context._class->variables[i].expression) {
+ if (p_line <= context._class->variables[i].line)
+ return false;
bool rtype = _guess_expression_type(context, context._class->variables[i].expression, context._class->variables[i].line, r_type);
if (rtype && r_type.type != Variant::NIL)
@@ -2102,9 +2118,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
for (List<String>::Element *E = opts.front(); E; E = E->next()) {
String opt = E->get().strip_edges();
- if (opt.begins_with("\"") && opt.ends_with("\"")) {
+ if (opt.is_quoted()) {
r_forced = true;
- String idopt = opt.substr(1, opt.length() - 2);
+ String idopt = opt.unquote();
if (idopt.replace("/", "_").is_valid_identifier()) {
options.insert(idopt);
} else {
@@ -2760,31 +2776,31 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
}
//global
- for (Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) {
- if (E->key() == p_symbol) {
-
- Variant value = GDScriptLanguage::get_singleton()->get_global_array()[E->get()];
- if (value.get_type() == Variant::OBJECT) {
- Object *obj = value;
- if (obj) {
-
- if (Object::cast_to<GDNativeClass>(obj)) {
- r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
- r_result.class_name = Object::cast_to<GDNativeClass>(obj)->get_name();
-
- } else {
- r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
- r_result.class_name = obj->get_class();
- }
- return OK;
+ Map<StringName, int> classes = GDScriptLanguage::get_singleton()->get_global_map();
+ if (classes.has(p_symbol)) {
+ Variant value = GDScriptLanguage::get_singleton()->get_global_array()[classes[p_symbol]];
+ if (value.get_type() == Variant::OBJECT) {
+ Object *obj = value;
+ if (obj) {
+ if (Object::cast_to<GDNativeClass>(obj)) {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
+ r_result.class_name = Object::cast_to<GDNativeClass>(obj)->get_name();
+ } else {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
+ r_result.class_name = obj->get_class();
}
- } else {
- r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
- r_result.class_name = "@Global Scope";
- r_result.class_member = p_symbol;
+ // proxy class remove the underscore.
+ if (r_result.class_name.begins_with("_")) {
+ r_result.class_name = r_result.class_name.right(1);
+ }
return OK;
}
+ } else {
+ r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
+ r_result.class_name = "@Global Scope";
+ r_result.class_member = p_symbol;
+ return OK;
}
}
}
diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp
index ce503b62f2..1a46ad324a 100644
--- a/modules/gdscript/gd_function.cpp
+++ b/modules/gdscript/gd_function.cpp
@@ -170,7 +170,7 @@ static String _get_var_type(const Variant *p_type) {
return basestr;
}
-#if defined(__GNUC__) && !defined(__clang__)
+#if defined(__GNUC__)
#define OPCODES_TABLE \
static const void *switch_table_ops[] = { \
&&OPCODE_OPERATOR, \
@@ -427,8 +427,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 5;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_EXTENDS_TEST) {
CHECK_SPACE(4);
@@ -492,8 +493,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = extends_ok;
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET) {
CHECK_SPACE(3);
@@ -518,8 +520,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET) {
CHECK_SPACE(3);
@@ -550,8 +553,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET_NAMED) {
CHECK_SPACE(3);
@@ -575,8 +579,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET_NAMED) {
CHECK_SPACE(4);
@@ -609,8 +614,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET_MEMBER) {
CHECK_SPACE(3);
@@ -631,8 +637,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET_MEMBER) {
CHECK_SPACE(3);
@@ -649,8 +656,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN) {
CHECK_SPACE(3);
@@ -660,8 +668,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = *src;
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN_TRUE) {
CHECK_SPACE(2);
@@ -670,8 +679,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = true;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN_FALSE) {
CHECK_SPACE(2);
@@ -680,8 +690,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = false;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT) {
CHECK_SPACE(2);
@@ -708,8 +719,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
ip += 4 + argc;
//construct a basic type
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT_ARRAY) {
CHECK_SPACE(1);
@@ -728,8 +740,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = array;
ip += 3 + argc;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
CHECK_SPACE(1);
@@ -750,8 +763,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = dict;
ip += 3 + argc * 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_RETURN)
OPCODE(OPCODE_CALL) {
@@ -830,8 +844,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
//_call_func(NULL,base,*methodname,ip,argc,p_instance,stack);
ip += argc + 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_BUILT_IN) {
CHECK_SPACE(4);
@@ -869,12 +884,14 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += argc + 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_SELF) {
OPCODE_BREAK;
}
+
OPCODE(OPCODE_CALL_SELF_BASE) {
CHECK_SPACE(2);
@@ -948,8 +965,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
ip += 4 + argc;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_YIELD)
OPCODE(OPCODE_YIELD_SIGNAL) {
@@ -1032,6 +1050,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
exit_ok = true;
OPCODE_BREAK;
}
+
OPCODE(OPCODE_YIELD_RESUME) {
CHECK_SPACE(2);
@@ -1044,8 +1063,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
GET_VARIANT_PTR(result, 1);
*result = p_state->result;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP) {
CHECK_SPACE(2);
@@ -1053,8 +1073,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_IF) {
CHECK_SPACE(3);
@@ -1067,11 +1088,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int to = _code_ptr[ip + 2];
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
+ } else {
+ ip += 3;
}
- ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_IF_NOT) {
CHECK_SPACE(3);
@@ -1084,17 +1106,19 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int to = _code_ptr[ip + 2];
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
+ } else {
+ ip += 3;
}
- ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) {
CHECK_SPACE(2);
ip = _default_arg_ptr[defarg];
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_RETURN) {
CHECK_SPACE(2);
@@ -1103,6 +1127,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
exit_ok = true;
OPCODE_BREAK;
}
+
OPCODE(OPCODE_ITERATE_BEGIN) {
CHECK_SPACE(8); //space for this a regular iterate
@@ -1121,20 +1146,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int jumpto = _code_ptr[ip + 3];
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
ip = jumpto;
- DISPATCH_OPCODE;
- }
- GET_VARIANT_PTR(iterator, 4);
+ } else {
+ GET_VARIANT_PTR(iterator, 4);
- *iterator = container->iter_get(*counter, valid);
+ *iterator = container->iter_get(*counter, valid);
#ifdef DEBUG_ENABLED
- if (!valid) {
- err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'.";
- OPCODE_BREAK;
- }
+ if (!valid) {
+ err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'.";
+ OPCODE_BREAK;
+ }
#endif
- ip += 5; //skip regular iterate which is always next
- DISPATCH_OPCODE;
+ ip += 5; //skip regular iterate which is always next
+ }
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ITERATE) {
CHECK_SPACE(4);
@@ -1153,20 +1179,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int jumpto = _code_ptr[ip + 3];
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
ip = jumpto;
- DISPATCH_OPCODE;
- }
- GET_VARIANT_PTR(iterator, 4);
+ } else {
+ GET_VARIANT_PTR(iterator, 4);
- *iterator = container->iter_get(*counter, valid);
+ *iterator = container->iter_get(*counter, valid);
#ifdef DEBUG_ENABLED
- if (!valid) {
- err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
- OPCODE_BREAK;
- }
+ if (!valid) {
+ err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
+ OPCODE_BREAK;
+ }
#endif
- ip += 5; //loop again
- DISPATCH_OPCODE;
+ ip += 5; //loop again
+ }
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(2);
GET_VARIANT_PTR(test, 1);
@@ -1182,8 +1209,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
#endif
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_BREAKPOINT) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
@@ -1191,8 +1219,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_LINE) {
CHECK_SPACE(2);
@@ -1220,8 +1249,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
ScriptDebugger::get_singleton()->line_poll();
}
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_END) {
exit_ok = true;
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp
index 34d01c6beb..b43ec409a1 100644
--- a/modules/gdscript/gd_functions.cpp
+++ b/modules/gdscript/gd_functions.cpp
@@ -83,6 +83,8 @@ const char *GDFunctions::get_func_name(Function p_func) {
"rad2deg",
"linear2db",
"db2linear",
+ "wrapi",
+ "wrapf",
"max",
"min",
"clamp",
@@ -405,6 +407,14 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count,
VALIDATE_ARG_NUM(0);
r_ret = Math::db2linear((double)*p_args[0]);
} break;
+ case MATH_WRAP: {
+ VALIDATE_ARG_COUNT(3);
+ r_ret = Math::wrapi((int64_t)*p_args[0], (int64_t)*p_args[1], (int64_t)*p_args[2]);
+ } break;
+ case MATH_WRAPF: {
+ VALIDATE_ARG_COUNT(3);
+ r_ret = Math::wrapf((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
+ } break;
case LOGIC_MAX: {
VALIDATE_ARG_COUNT(2);
if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) {
@@ -1285,6 +1295,8 @@ bool GDFunctions::is_deterministic(Function p_func) {
case MATH_RAD2DEG:
case MATH_LINEAR2DB:
case MATH_DB2LINEAR:
+ case MATH_WRAP:
+ case MATH_WRAPF:
case LOGIC_MAX:
case LOGIC_MIN:
case LOGIC_CLAMP:
@@ -1513,6 +1525,16 @@ MethodInfo GDFunctions::get_info(Function p_func) {
mi.return_val.type = Variant::REAL;
return mi;
} break;
+ case MATH_WRAP: {
+ MethodInfo mi("wrapi", PropertyInfo(Variant::INT, "value"), PropertyInfo(Variant::INT, "min"), PropertyInfo(Variant::INT, "max"));
+ mi.return_val.type = Variant::INT;
+ return mi;
+ } break;
+ case MATH_WRAPF: {
+ MethodInfo mi("wrapf", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
+ mi.return_val.type = Variant::REAL;
+ return mi;
+ } break;
case LOGIC_MAX: {
MethodInfo mi("max", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
mi.return_val.type = Variant::REAL;
diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h
index a568c8f1cf..0de09f2e71 100644
--- a/modules/gdscript/gd_functions.h
+++ b/modules/gdscript/gd_functions.h
@@ -75,6 +75,8 @@ public:
MATH_RAD2DEG,
MATH_LINEAR2DB,
MATH_DB2LINEAR,
+ MATH_WRAP,
+ MATH_WRAPF,
LOGIC_MAX,
LOGIC_MIN,
LOGIC_CLAMP,
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 36aaa1f807..d7e83c3a33 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -362,6 +362,13 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
constant->value = Math_PI;
tokenizer->advance();
expr = constant;
+ } else if (tokenizer->get_token() == GDTokenizer::TK_CONST_TAU) {
+
+ //constant defined by tokenizer
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ constant->value = Math_TAU;
+ tokenizer->advance();
+ expr = constant;
} else if (tokenizer->get_token() == GDTokenizer::TK_CONST_INF) {
//constant defined by tokenizer
@@ -1906,7 +1913,8 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) {
// all the constants like strings and numbers
default: {
Node *value = _parse_and_reduce_expression(pattern, p_static);
- if (error_set) {
+ if (!value) {
+ _set_error("Expect constant expression or variables in a pattern");
return NULL;
}
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index cf6529d5ae..e5016c59bd 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -609,11 +609,6 @@ Error GDScript::reload(bool p_keep_state) {
return OK;
}
-String GDScript::get_node_type() const {
-
- return ""; // ?
-}
-
ScriptLanguage *GDScript::get_language() const {
return GDScriptLanguage::get_singleton();
@@ -1329,6 +1324,7 @@ void GDScriptLanguage::init() {
}
_add_global(StaticCString::create("PI"), Math_PI);
+ _add_global(StaticCString::create("TAU"), Math_TAU);
_add_global(StaticCString::create("INF"), Math_INF);
_add_global(StaticCString::create("NAN"), Math_NAN);
@@ -1705,6 +1701,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"bool",
"null",
"PI",
+ "TAU",
"INF",
"NAN",
"self",
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 5e1a8b19ac..e0d142014a 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -172,7 +172,6 @@ public:
virtual Error reload(bool p_keep_state = false);
- virtual String get_node_type() const;
void set_script_path(const String &p_path) { path = p_path; } //because subclasses need a path too...
Error load_source_code(const String &p_path);
Error load_byte_code(const String &p_path);
@@ -386,6 +385,7 @@ public:
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
+ virtual bool supports_builtin_mode() const;
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 5f85158232..98ac0f473d 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -123,6 +123,7 @@ const char *GDTokenizer::token_names[TK_MAX] = {
"'$'",
"'\\n'",
"PI",
+ "TAU",
"_",
"INF",
"NAN",
@@ -217,6 +218,7 @@ static const _kws _keyword_list[] = {
{ GDTokenizer::TK_CF_PASS, "pass" },
{ GDTokenizer::TK_SELF, "self" },
{ GDTokenizer::TK_CONST_PI, "PI" },
+ { GDTokenizer::TK_CONST_TAU, "TAU" },
{ GDTokenizer::TK_WILDCARD, "_" },
{ GDTokenizer::TK_CONST_INF, "INF" },
{ GDTokenizer::TK_CONST_NAN, "NAN" },
@@ -280,6 +282,7 @@ bool GDTokenizer::is_token_literal(int p_offset, bool variable_safe) const {
case TK_CF_PASS:
case TK_SELF:
case TK_CONST_PI:
+ case TK_CONST_TAU:
case TK_WILDCARD:
case TK_CONST_INF:
case TK_CONST_NAN:
diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h
index c935ce45a1..f4b579def4 100644
--- a/modules/gdscript/gd_tokenizer.h
+++ b/modules/gdscript/gd_tokenizer.h
@@ -128,6 +128,7 @@ public:
TK_DOLLAR,
TK_NEWLINE,
TK_CONST_PI,
+ TK_CONST_TAU,
TK_WILDCARD,
TK_CONST_INF,
TK_CONST_NAN,
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index cd01233ce4..5b0fe56f25 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GridMap" inherits="Spatial" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Node for 3D tile-based maps.
</brief_description>
<description>
+ GridMap lets you place meshes on a grid interactively. It works both from the editor and can help you create in-game level editors.
+ GridMaps use a [MeshLibrary] which contain a list of tiles: meshes with materials plus optional collisions and extra elements.
+ A GridMap contains a collection of cells. Each grid cell refers to a [MeshLibrary] item. All cells in the map have the same dimensions.
+ A GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells.
</description>
<tutorials>
</tutorials>
@@ -13,6 +18,7 @@
<return type="void">
</return>
<description>
+ Clear all cells.
</description>
</method>
<method name="get_cell_item" qualifiers="const">
@@ -25,6 +31,7 @@
<argument index="2" name="z" type="int">
</argument>
<description>
+ The [MeshLibrary] item index located at the grid-based X, Y and Z coordinates. If the cell is empty, [INVALID_CELL_ITEM] will be returned.
</description>
</method>
<method name="get_cell_item_orientation" qualifiers="const">
@@ -37,54 +44,75 @@
<argument index="2" name="z" type="int">
</argument>
<description>
+ The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is retuned if the cell is empty.
</description>
</method>
<method name="get_cell_size" qualifiers="const">
<return type="Vector3">
</return>
<description>
+ The dimensions of the grid's cells.
</description>
</method>
<method name="get_center_x" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the X axis.
</description>
</method>
<method name="get_center_y" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the Y axis.
</description>
</method>
<method name="get_center_z" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the Z axis.
</description>
</method>
<method name="get_meshes">
<return type="Array">
</return>
<description>
+ Array of [Transform] and [Mesh] references corresponding to the non empty cells in the grid. The transforms are specified in world space.
</description>
</method>
<method name="get_octant_size" qualifiers="const">
<return type="int">
</return>
<description>
+ The size of each octant measured in number of cells. This applies to all three axis.
</description>
</method>
<method name="get_theme" qualifiers="const">
<return type="MeshLibrary">
</return>
<description>
+ The assigned [MeshLibrary].
</description>
</method>
<method name="get_used_cells" qualifiers="const">
<return type="Array">
</return>
<description>
+ Array of [Vector3] with the non empty cell coordinates in the grid map.
+ </description>
+ </method>
+ <method name="map_to_world" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <argument index="2" name="z" type="int">
+ </argument>
+ <description>
</description>
</method>
<method name="resource_changed">
@@ -109,6 +137,9 @@
<argument index="4" name="orientation" type="int" default="0">
</argument>
<description>
+ Set the mesh index for the cell referenced by its grid-based X, Y and Z coordinates.
+ A negative item index will clear the cell.
+ Optionally, the item's orientation can be passed.
</description>
</method>
<method name="set_cell_size">
@@ -117,6 +148,7 @@
<argument index="0" name="size" type="Vector3">
</argument>
<description>
+ Sets the height, width and depth of the grid's cells.
</description>
</method>
<method name="set_center_x">
@@ -125,6 +157,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the X axis. By default it is enabled.
</description>
</method>
<method name="set_center_y">
@@ -133,6 +166,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the Y axis. By default it is enabled.
</description>
</method>
<method name="set_center_z">
@@ -141,6 +175,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the Z axis. By default it is enabled.
</description>
</method>
<method name="set_clip">
@@ -163,6 +198,7 @@
<argument index="0" name="size" type="int">
</argument>
<description>
+ Sets the size for each octant measured in number of cells. This applies to all three axis.
</description>
</method>
<method name="set_theme">
@@ -171,11 +207,21 @@
<argument index="0" name="theme" type="MeshLibrary">
</argument>
<description>
+ Sets the collection of meshes for the map.
+ </description>
+ </method>
+ <method name="world_to_map" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="pos" type="Vector3">
+ </argument>
+ <description>
</description>
</method>
</methods>
<constants>
<constant name="INVALID_CELL_ITEM" value="-1" enum="">
+ Invalid cell item that can be used in [method set_cell_item] to clear cells (or represent an empty cell in [method get_cell_item]).
</constant>
</constants>
</class>
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 4e8b67e4e8..cb14a5ee9c 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -333,6 +333,23 @@ int GridMap::get_cell_item_orientation(int p_x, int p_y, int p_z) const {
return cell_map[key].rot;
}
+Vector3 GridMap::world_to_map(const Vector3 &p_world_pos) const {
+ Vector3 map_pos = p_world_pos / cell_size;
+ map_pos.x = floor(map_pos.x);
+ map_pos.y = floor(map_pos.y);
+ map_pos.z = floor(map_pos.z);
+ return map_pos;
+}
+
+Vector3 GridMap::map_to_world(int p_x, int p_y, int p_z) const {
+ Vector3 offset = _get_offset();
+ Vector3 world_pos(
+ p_x * cell_size.x + offset.x,
+ p_y * cell_size.y + offset.y,
+ p_z * cell_size.z + offset.z);
+ return world_pos;
+}
+
void GridMap::_octant_transform(const OctantKey &p_key) {
ERR_FAIL_COND(!octant_map.has(p_key));
@@ -407,7 +424,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//print_line("OCTANT, CELLS: "+itos(ii.cells.size()));
Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z);
- Vector3 ofs(cell_size.x * 0.5 * int(center_x), cell_size.y * 0.5 * int(center_y), cell_size.z * 0.5 * int(center_z));
+ Vector3 ofs = _get_offset();
Transform xform;
@@ -754,6 +771,9 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cell_item", "x", "y", "z"), &GridMap::get_cell_item);
ClassDB::bind_method(D_METHOD("get_cell_item_orientation", "x", "y", "z"), &GridMap::get_cell_item_orientation);
+ ClassDB::bind_method(D_METHOD("world_to_map", "pos"), &GridMap::world_to_map);
+ ClassDB::bind_method(D_METHOD("map_to_world", "x", "y", "z"), &GridMap::map_to_world);
+
//ClassDB::bind_method(D_METHOD("_recreate_octants"),&GridMap::_recreate_octants);
ClassDB::bind_method(D_METHOD("_update_octants_callback"), &GridMap::_update_octants_callback);
ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &GridMap::resource_changed);
@@ -801,7 +821,7 @@ void GridMap::set_clip(bool p_enabled, bool p_clip_above, int p_floor, Vector3::
void GridMap::set_cell_scale(float p_scale) {
cell_scale = p_scale;
- _queue_octants_dirty();
+ _recreate_octant_data();
}
float GridMap::get_cell_scale() const {
@@ -827,7 +847,7 @@ Array GridMap::get_meshes() {
if (theme.is_null())
return Array();
- Vector3 ofs(cell_size.x * 0.5 * int(center_x), cell_size.y * 0.5 * int(center_y), cell_size.z * 0.5 * int(center_z));
+ Vector3 ofs = _get_offset();
Array meshes;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) {
@@ -857,6 +877,13 @@ Array GridMap::get_meshes() {
return meshes;
}
+Vector3 GridMap::_get_offset() const {
+ return Vector3(
+ cell_size.x * 0.5 * int(center_x),
+ cell_size.y * 0.5 * int(center_y),
+ cell_size.z * 0.5 * int(center_z));
+}
+
GridMap::GridMap() {
cell_size = Vector3(2, 2, 2);
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index 296956ff5d..5bfdf1dac3 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -184,6 +184,8 @@ class GridMap : public Spatial {
void _clear_internal();
+ Vector3 _get_offset() const;
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -218,6 +220,9 @@ public:
int get_cell_item(int p_x, int p_y, int p_z) const;
int get_cell_item_orientation(int p_x, int p_y, int p_z) const;
+ Vector3 world_to_map(const Vector3 &p_pos) const;
+ Vector3 map_to_world(int p_x, int p_y, int p_z) const;
+
void set_clip(bool p_enabled, bool p_clip_above = true, int p_floor = 0, Vector3::Axis p_axis = Vector3::AXIS_X);
void set_cell_scale(float p_scale);
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index 92d88207b3..08ac624504 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -38,7 +38,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
String header = f->get_token();
- print_line("HEADER: " + header);
ERR_FAIL_COND_V(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED);
while (true) {
@@ -64,8 +63,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
int width = f->get_line().to_int();
- print_line("HDR w: " + itos(width) + " h:" + itos(height));
-
PoolVector<uint8_t> imgdata;
imgdata.resize(height * width * sizeof(uint32_t));
@@ -102,7 +99,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
len <<= 8;
len |= f->get_8();
- print_line("line: " + itos(len));
if (len != width) {
ERR_EXPLAIN("invalid decoded scanline length, corrupt HDR");
ERR_FAIL_V(ERR_FILE_CORRUPT);
diff --git a/modules/mobile_vr/mobile_interface.cpp b/modules/mobile_vr/mobile_interface.cpp
index eb87bb2cf0..3a0b83d534 100644
--- a/modules/mobile_vr/mobile_interface.cpp
+++ b/modules/mobile_vr/mobile_interface.cpp
@@ -122,6 +122,7 @@ void MobileVRInterface::set_position_from_sensors() {
Vector3 north(0.0, 0.0, 1.0); // North is Z positive
// make copies of our inputs
+ bool has_grav = false;
Vector3 acc = input->get_accelerometer();
Vector3 gyro = input->get_gyroscope();
Vector3 grav = input->get_gravity();
@@ -143,25 +144,17 @@ void MobileVRInterface::set_position_from_sensors() {
// what a stable gravity vector is
grav = acc;
if (grav.length() > 0.1) {
- has_gyro = true;
+ has_grav = true;
};
} else {
- has_gyro = true;
+ has_grav = true;
};
bool has_magneto = magneto.length() > 0.1;
- bool has_grav = grav.length() > 0.1;
-
-#ifdef ANDROID_ENABLED
- ///@TODO needs testing, i don't have a gyro, potentially can be removed depending on what comes out of issue #8101
- // On Android x and z axis seem inverted
- gyro.x = -gyro.x;
- gyro.z = -gyro.z;
- grav.x = -grav.x;
- grav.z = -grav.z;
- magneto.x = -magneto.x;
- magneto.z = -magneto.z;
-#endif
+ if (gyro.length() > 0.1) {
+ /* this can return to 0.0 if the user doesn't move the phone, so once on, it's on */
+ has_gyro = true;
+ };
if (has_gyro) {
// start with applying our gyro (do NOT smooth our gyro!)
@@ -330,7 +323,7 @@ void MobileVRInterface::uninitialize() {
};
};
-Size2 MobileVRInterface::get_recommended_render_targetsize() {
+Size2 MobileVRInterface::get_render_targetsize() {
_THREAD_SAFE_METHOD_
// we use half our window size
diff --git a/modules/mobile_vr/mobile_interface.h b/modules/mobile_vr/mobile_interface.h
index 6a5e01c163..b652edc1c6 100644
--- a/modules/mobile_vr/mobile_interface.h
+++ b/modules/mobile_vr/mobile_interface.h
@@ -90,7 +90,7 @@ private:
///@TODO a few support functions for trackers, most are math related and should likely be moved elsewhere
float floor_decimals(float p_value, float p_decimals) {
- float power_of_10 = pow(10.0, p_decimals);
+ float power_of_10 = pow(10.0f, p_decimals);
return floor(p_value * power_of_10) / power_of_10;
};
@@ -137,7 +137,7 @@ public:
virtual bool initialize();
virtual void uninitialize();
- virtual Size2 get_recommended_render_targetsize();
+ virtual Size2 get_render_targetsize();
virtual bool is_stereo();
virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index caf4fdb3ca..18a20ecac4 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -53,68 +53,155 @@ if env['tools']:
vars = Variables()
vars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True))
+vars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False))
vars.Update(env)
# Glue sources
if env['mono_glue']:
env.add_source_files(env.modules_sources, 'glue/*.cpp')
else:
- env.Append(CPPDEFINES = [ 'MONO_GLUE_DISABLED' ])
+ env.Append(CPPDEFINES=['MONO_GLUE_DISABLED'])
if ARGUMENTS.get('yolo_copy', False):
- env.Append(CPPDEFINES = [ 'YOLO_COPY' ])
+ env.Append(CPPDEFINES=['YOLO_COPY'])
+
# Build GodotSharpTools solution
+
import os
-import subprocess
-import mono_reg_utils as monoreg
+
+
+def find_msbuild_unix(filename):
+ import os.path
+ import sys
+
+ hint_dirs = ['/opt/novell/mono/bin']
+ if sys.platform == "darwin":
+ hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin'] + hint_dirs
+
+ for hint_dir in hint_dirs:
+ hint_path = os.path.join(hint_dir, filename)
+ if os.path.isfile(hint_path):
+ return hint_path
+ elif os.path.isfile(hint_path + ".exe"):
+ return hint_path + ".exe"
+
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
+ hint_dir = hint_dir.strip('"')
+ hint_path = os.path.join(hint_dir, filename)
+ if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
+ return hint_path
+ if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
+ return hint_path + ".exe"
+
+ return None
+
+
+def find_msbuild_windows():
+ import mono_reg_utils as monoreg
+
+ bits = env['bits']
+
+ if bits == '32':
+ if os.getenv('MONO32_PREFIX'):
+ mono_root = os.getenv('MONO32_PREFIX')
+ else:
+ mono_root = monoreg.find_mono_root_dir(bits)
+ else:
+ if os.getenv('MONO64_PREFIX'):
+ mono_root = os.getenv('MONO64_PREFIX')
+ else:
+ mono_root = monoreg.find_mono_root_dir(bits)
+
+ if not mono_root:
+ raise RuntimeError('Cannot find mono root directory')
+
+ msbuild_tools_path = monoreg.find_msbuild_tools_path_reg()
+
+ if msbuild_tools_path:
+ return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), os.path.join(mono_root, 'lib', 'mono', '4.5'))
+ else:
+ msbuild_mono = os.path.join(mono_root, 'bin', 'msbuild.bat')
+
+ if os.path.isfile(msbuild_mono):
+ return (msbuild_mono, '')
+
+ return None
def mono_build_solution(source, target, env):
+ import subprocess
+ import mono_reg_utils as monoreg
+ from shutil import copyfile
+
+ framework_path_override = ''
+
if os.name == 'nt':
- msbuild_tools_path = monoreg.find_msbuild_tools_path_reg()
- if not msbuild_tools_path:
- raise RuntimeError('Cannot find MSBuild Tools Path in the registry')
- msbuild_path = os.path.join(msbuild_tools_path, 'MSBuild.exe')
+ msbuild_info = find_msbuild_windows()
+ if msbuild_info is None:
+ raise RuntimeError('Cannot find MSBuild executable')
+ msbuild_path = msbuild_info[0]
+ framework_path_override = msbuild_info[1]
else:
- msbuild_path = 'msbuild'
+ msbuild_path = find_msbuild_unix('msbuild')
+ if msbuild_path is None:
+ xbuild_fallback = env['xbuild_fallback']
+
+ if xbuild_fallback and os.name == 'nt':
+ print("Option 'xbuild_fallback' not supported on Windows")
+ xbuild_fallback = False
+
+ if xbuild_fallback:
+ print('Cannot find MSBuild executable, trying with xbuild')
+ print('Warning: xbuild is deprecated')
+
+ msbuild_path = find_msbuild_unix('xbuild')
+
+ if msbuild_path is None:
+ raise RuntimeError('Cannot find xbuild executable')
+ else:
+ raise RuntimeError('Cannot find MSBuild executable')
+
+ print('MSBuild path: ' + msbuild_path)
- output_path = os.path.abspath(os.path.join(str(target[0]), os.pardir))
+ build_config = 'Release'
msbuild_args = [
msbuild_path,
os.path.abspath(str(source[0])),
- '/p:Configuration=Release',
- '/p:OutputPath=' + output_path
+ '/p:Configuration=' + build_config,
]
+ if framework_path_override:
+ msbuild_args += ['/p:FrameworkPathOverride=' + framework_path_override]
+
msbuild_env = os.environ.copy()
# Needed when running from Developer Command Prompt for VS
if 'PLATFORM' in msbuild_env:
del msbuild_env['PLATFORM']
- msbuild_alt_paths = [ 'xbuild' ]
-
- while True:
- try:
- subprocess.check_call(msbuild_args, env = msbuild_env)
- break
- except subprocess.CalledProcessError:
- raise RuntimeError('GodotSharpTools build failed')
- except OSError:
- if os.name != 'nt':
- if not msbuild_alt_paths:
- raise RuntimeError('Could not find commands msbuild or xbuild')
- # Try xbuild
- msbuild_args[0] = msbuild_alt_paths.pop(0)
- else:
- raise RuntimeError('Could not find command MSBuild.exe')
+ try:
+ subprocess.check_call(msbuild_args, env=msbuild_env)
+ except subprocess.CalledProcessError:
+ raise RuntimeError('GodotSharpTools build failed')
+
+ src_dir = os.path.abspath(os.path.join(str(source[0]), os.pardir, 'bin', build_config))
+ dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir))
+
+ if not os.path.isdir(dst_dir):
+ if os.path.exists(dst_dir):
+ raise RuntimeError('Target directory is a file')
+ os.makedirs(dst_dir)
+
+ asm_file = 'GodotSharpTools.dll'
+
+ copyfile(os.path.join(src_dir, asm_file), os.path.join(dst_dir, asm_file))
mono_sln_builder = Builder(action = mono_build_solution)
-env.Append(BUILDERS = { 'MonoBuildSolution' : mono_sln_builder })
+env.Append(BUILDERS={'MonoBuildSolution': mono_sln_builder})
env.MonoBuildSolution(
os.path.join(Dir('#bin').abspath, 'GodotSharpTools.dll'),
'editor/GodotSharpTools/GodotSharpTools.sln'
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 9de199bb5a..7ad135e0b9 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -2,7 +2,6 @@
import imp
import os
import sys
-from shutil import copyfile
from SCons.Script import BoolVariable, Environment, Variables
@@ -16,8 +15,7 @@ def find_file_in_dir(directory, files, prefix='', extension=''):
for curfile in files:
if os.path.isfile(os.path.join(directory, prefix + curfile + extension)):
return curfile
-
- return None
+ return ''
def can_build(platform):
@@ -31,13 +29,32 @@ def is_enabled():
return False
+def copy_file_no_replace(src_dir, dst_dir, name):
+ from shutil import copyfile
+
+ src_path = os.path.join(src_dir, name)
+ dst_path = os.path.join(dst_dir, name)
+ need_copy = True
+
+ if not os.path.isdir(dst_dir):
+ os.mkdir(dst_dir)
+ elif os.path.exists(dst_path):
+ need_copy = False
+
+ if need_copy:
+ copyfile(src_path, dst_path)
+
+
def configure(env):
env.use_ptrcall = True
+ env.add_module_version_string("mono")
envvars = Variables()
envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
envvars.Update(env)
+ bits = env['bits']
+
mono_static = env['mono_static']
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
@@ -46,18 +63,18 @@ def configure(env):
if mono_static:
raise RuntimeError('mono-static: Not supported on Windows')
- if env['bits'] == '32':
+ if bits == '32':
if os.getenv('MONO32_PREFIX'):
mono_root = os.getenv('MONO32_PREFIX')
elif os.name == 'nt':
- mono_root = monoreg.find_mono_root_dir()
+ mono_root = monoreg.find_mono_root_dir(bits)
else:
if os.getenv('MONO64_PREFIX'):
mono_root = os.getenv('MONO64_PREFIX')
elif os.name == 'nt':
- mono_root = monoreg.find_mono_root_dir()
+ mono_root = monoreg.find_mono_root_dir(bits)
- if mono_root is None:
+ if not mono_root:
raise RuntimeError('Mono installation directory not found')
mono_lib_path = os.path.join(mono_root, 'lib')
@@ -67,7 +84,7 @@ def configure(env):
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
- if mono_lib_name is None:
+ if not mono_lib_name:
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
if os.getenv('VCINSTALLDIR'):
@@ -79,28 +96,23 @@ def configure(env):
mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll')
- mono_dll_src = os.path.join(mono_bin_path, mono_dll_name + '.dll')
- mono_dll_dst = os.path.join('bin', mono_dll_name + '.dll')
- copy_mono_dll = True
+ if not mono_dll_name:
+ raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
- if not os.path.isdir('bin'):
- os.mkdir('bin')
- elif os.path.exists(mono_dll_dst):
- copy_mono_dll = False
-
- if copy_mono_dll:
- copyfile(mono_dll_src, mono_dll_dst)
+ copy_file_no_replace(mono_bin_path, 'bin', mono_dll_name + '.dll')
else:
- mono_root = None
+ sharedlib_ext = '.dylib' if sys.platform == 'darwin' else '.so'
+
+ mono_root = ''
- if env['bits'] == '32':
+ if bits == '32':
if os.getenv('MONO32_PREFIX'):
mono_root = os.getenv('MONO32_PREFIX')
else:
if os.getenv('MONO64_PREFIX'):
mono_root = os.getenv('MONO64_PREFIX')
- if mono_root is not None:
+ if mono_root:
mono_lib_path = os.path.join(mono_root, 'lib')
env.Append(LIBPATH=mono_lib_path)
@@ -108,7 +120,7 @@ def configure(env):
mono_lib = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension='.a')
- if mono_lib is None:
+ if not mono_lib:
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
env.Append(CPPFLAGS=['-D_REENTRANT'])
@@ -125,12 +137,41 @@ def configure(env):
else:
env.Append(LIBS=[mono_lib])
- env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+ if sys.platform == "darwin":
+ env.Append(LIBS=['iconv', 'pthread'])
+ elif sys.platform == "linux" or sys.platform == "linux2":
+ env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+
+ if not mono_static:
+ mono_so_name = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension=sharedlib_ext)
+
+ if not mono_so_name:
+ raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
+
+ copy_file_no_replace(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
else:
if mono_static:
raise RuntimeError('mono-static: Not supported with pkg-config. Specify a mono prefix manually')
- env.ParseConfig('pkg-config mono-2 --cflags --libs')
+ env.ParseConfig('pkg-config monosgen-2 --cflags --libs')
+
+ mono_lib_path = ''
+ mono_so_name = ''
+
+ tmpenv = Environment()
+ tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
+
+ for hint_dir in tmpenv['LIBPATH']:
+ name_found = find_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=sharedlib_ext)
+ if name_found:
+ mono_lib_path = hint_dir
+ mono_so_name = name_found
+ break
+
+ if not mono_so_name:
+ raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
+
+ copy_file_no_replace(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
env.Append(LINKFLAGS='-rdynamic')
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index b475782729..161e130a07 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -41,6 +41,7 @@
#include "editor/csharp_project.h"
#include "editor/editor_node.h"
#include "editor/godotsharp_editor.h"
+#include "utils/string_utils.h"
#endif
#include "godotsharp_dirs.h"
@@ -48,8 +49,9 @@
#include "mono_gd/gd_mono_marshal.h"
#include "signal_awaiter_utils.h"
-#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->string_names.m_var)
+#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
+#ifdef TOOLS_ENABLED
static bool _create_project_solution_if_needed() {
String sln_path = GodotSharpDirs::get_project_sln_path();
@@ -64,6 +66,7 @@ static bool _create_project_solution_if_needed() {
return true;
}
+#endif
CSharpLanguage *CSharpLanguage::singleton = NULL;
@@ -119,6 +122,9 @@ void CSharpLanguage::init() {
void CSharpLanguage::finish() {
+ // Release gchandle bindings before finalizing mono runtime
+ gchandle_bindings.clear();
+
if (gdmono) {
memdelete(gdmono);
gdmono = NULL;
@@ -274,17 +280,40 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
" // Initialization here\n"
" \n"
" }\n"
+ "\n"
+ "// public override void _Process(float delta)\n"
+ "// {\n"
+ "// // Called every frame. Delta is time since last frame.\n"
+ "// // Update game logic here.\n"
+ "// \n"
+ "// }\n"
"}\n";
- script_template = script_template.replace("%BASE_CLASS_NAME%", p_base_class_name).replace("%CLASS_NAME%", p_class_name);
+ script_template = script_template.replace("%BASE_CLASS_NAME%", p_base_class_name)
+ .replace("%CLASS_NAME%", p_class_name);
Ref<CSharpScript> script;
script.instance();
script->set_source_code(script_template);
+ script->set_name(p_class_name);
return script;
}
+bool CSharpLanguage::is_using_templates() {
+
+ return true;
+}
+
+void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+
+ String src = p_script->get_source_code();
+ src = src.replace("%BASE%", p_base_class_name)
+ .replace("%CLASS%", p_class_name)
+ .replace("%TS%", _get_indentation());
+ p_script->set_source_code(src);
+}
+
Script *CSharpLanguage::create_script() const {
return memnew(CSharpScript);
@@ -292,23 +321,115 @@ Script *CSharpLanguage::create_script() const {
bool CSharpLanguage::has_named_classes() const {
- return true;
+ return false;
}
-String CSharpLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+bool CSharpLanguage::supports_builtin_mode() const {
+ return false;
+}
+
+static String variant_type_to_managed_name(const String &p_var_type_name) {
+
+ if (p_var_type_name.empty())
+ return "object";
+
+ if (!ClassDB::class_exists(p_var_type_name)) {
+ Variant::Type var_types[] = {
+ Variant::BOOL,
+ Variant::INT,
+ Variant::REAL,
+ Variant::STRING,
+ Variant::VECTOR2,
+ Variant::RECT2,
+ Variant::VECTOR3,
+ Variant::TRANSFORM2D,
+ Variant::PLANE,
+ Variant::QUAT,
+ Variant::RECT3,
+ Variant::BASIS,
+ Variant::TRANSFORM,
+ Variant::COLOR,
+ Variant::NODE_PATH,
+ Variant::_RID
+ };
+
+ for (int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) {
+ if (p_var_type_name == Variant::get_type_name(var_types[i]))
+ return p_var_type_name;
+ }
+
+ if (p_var_type_name == "String")
+ return "string"; // I prefer this one >:[
+
+ // TODO these will be rewritten later into custom containers
+
+ if (p_var_type_name == "Array")
+ return "object[]";
+
+ if (p_var_type_name == "Dictionary")
+ return "Dictionary<object, object>";
+
+ if (p_var_type_name == "PoolByteArray")
+ return "byte[]";
+ if (p_var_type_name == "PoolIntArray")
+ return "int[]";
+ if (p_var_type_name == "PoolRealArray")
+ return "float[]";
+ if (p_var_type_name == "PoolStringArray")
+ return "string[]";
+ if (p_var_type_name == "PoolVector2Array")
+ return "Vector2[]";
+ if (p_var_type_name == "PoolVector3Array")
+ return "Vector3[]";
+ if (p_var_type_name == "PoolColorArray")
+ return "Color[]";
+
+ return "object";
+ }
+
+ return p_var_type_name;
+}
+
+String CSharpLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+#ifdef TOOLS_ENABLED
// FIXME
- // Due to Godot's API limitation this just appends the function to the end of the file
- // Another limitation is that the parameter types are not specified, so we must use System.Object
+ // - Due to Godot's API limitation this just appends the function to the end of the file
+ // - Use fully qualified name if there is ambiguity
String s = "private void " + p_name + "(";
for (int i = 0; i < p_args.size(); i++) {
+ const String &arg = p_args[i];
+
if (i > 0)
s += ", ";
- s += "object " + p_args[i];
+
+ s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0));
}
s += ")\n{\n // Replace with function body\n}\n";
return s;
+#else
+ return String();
+#endif
+}
+
+String CSharpLanguage::_get_indentation() const {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", 0);
+
+ if (use_space_indentation) {
+ int indent_size = EDITOR_DEF("text_editor/indent/size", 4);
+
+ String space_indent = "";
+ for (int i = 0; i < indent_size; i++) {
+ space_indent += " ";
+ }
+ return space_indent;
+ }
+ }
+#endif
+ return "\t";
}
void CSharpLanguage::frame() {
@@ -392,6 +513,7 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
(void)p_script; // UNUSED
#ifdef TOOLS_ENABLED
+ MonoReloadNode::get_singleton()->restart_reload_timer();
reload_assemblies_if_needed(p_soft_reload);
#endif
}
@@ -403,13 +525,17 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
+ String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
+
if (proj_assembly) {
String proj_asm_path = proj_assembly->get_path();
if (!FileAccess::exists(proj_assembly->get_path())) {
// Maybe it wasn't loaded from the default path, so check this as well
- String proj_asm_name = ProjectSettings::get_singleton()->get("application/config/name");
- proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(proj_asm_name);
+ proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name);
if (!FileAccess::exists(proj_asm_path))
return; // No assembly to load
}
@@ -417,8 +543,7 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
return; // Already up to date
} else {
- String proj_asm_name = ProjectSettings::get_singleton()->get("application/config/name");
- if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(proj_asm_name)))
+ if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name)))
return; // No assembly to load
}
}
@@ -536,6 +661,9 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
//if instance states were saved, set them!
}
+
+ if (Engine::get_singleton()->is_editor_hint())
+ EditorNode::get_singleton()->get_property_editor()->update_tree();
}
#endif
@@ -702,6 +830,14 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
void CSharpLanguage::free_instance_binding_data(void *p_data) {
+ if (GDMono::get_singleton() == NULL) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!gchandle_bindings.empty());
+#endif
+ // Mono runtime finalized, all the gchandle bindings were already released
+ return;
+ }
+
#ifndef NO_THREADS
script_bind_lock->lock();
#endif
@@ -903,46 +1039,6 @@ Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args,
} else {
return Variant();
}
- } else if (p_method == CACHED_STRING_NAME(_awaited_signal_callback)) {
- // shitty hack..
- // TODO move to its own function, thx
-
- if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- r_error.argument = 1;
- return Variant();
- }
-
- Ref<SignalAwaiterHandle> awaiter = *p_args[p_argcount - 1];
-
- if (awaiter.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = p_argcount - 1;
- r_error.expected = Variant::OBJECT;
- return Variant();
- }
-
- awaiter->set_completed(true);
-
- int extra_argc = p_argcount - 1;
- MonoArray *extra_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), extra_argc);
-
- for (int i = 0; i < extra_argc; i++) {
- MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
- mono_array_set(extra_args, MonoObject *, i, boxed);
- }
-
- GDMonoUtils::GodotObject__AwaitedSignalCallback thunk = CACHED_METHOD_THUNK(GodotObject, _AwaitedSignalCallback);
-
- MonoObject *ex = NULL;
- thunk(mono_object, &extra_args, awaiter->get_target(), &ex);
-
- if (ex) {
- mono_print_unhandled_exception(ex);
- ERR_FAIL_V(Variant());
- }
-
- return Variant();
}
top = top->get_parent_class();
@@ -1239,8 +1335,11 @@ bool CSharpScript::_update_exports() {
for (int i = 0; i < fields.size(); i++) {
GDMonoField *field = fields[i];
- if (field->is_static() || field->get_visibility() != GDMono::PUBLIC)
+ if (field->is_static()) {
+ if (field->has_attribute(CACHED_CLASS(ExportAttribute)))
+ ERR_PRINTS("Cannot export field because it is static: " + top->get_full_name() + "." + field->get_name());
continue;
+ }
String name = field->get_name();
StringName cname = name;
@@ -1248,17 +1347,39 @@ bool CSharpScript::_update_exports() {
if (member_info.has(cname))
continue;
- Variant::Type type = GDMonoMarshal::managed_to_variant_type(field->get_type());
+ ManagedType field_type = field->get_type();
+ Variant::Type type = GDMonoMarshal::managed_to_variant_type(field_type);
if (field->has_attribute(CACHED_CLASS(ExportAttribute))) {
+ // Field has Export attribute
MonoObject *attr = field->get_attribute(CACHED_CLASS(ExportAttribute));
- // Field has Export attribute
- int hint = CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr);
- String hint_string = CACHED_FIELD(ExportAttribute, hint_string)->get_string_value(attr);
- int usage = CACHED_FIELD(ExportAttribute, usage)->get_int_value(attr);
+ PropertyHint hint;
+ String hint_string;
+
+ if (type == Variant::NIL) {
+ ERR_PRINTS("Unknown type of exported field: " + top->get_full_name() + "." + field->get_name());
+ continue;
+ } else if (type == Variant::INT && field_type.type_encoding == MONO_TYPE_VALUETYPE && mono_class_is_enum(field_type.type_class->get_raw())) {
+ type = Variant::INT;
+ hint = PROPERTY_HINT_ENUM;
+
+ Vector<MonoClassField *> fields = field_type.type_class->get_enum_fields();
+
+ for (int i = 0; i < fields.size(); i++) {
+ if (i > 0)
+ hint_string += ",";
+ hint_string += mono_field_get_name(fields[i]);
+ }
+ } else if (type == Variant::OBJECT && CACHED_CLASS(GodotReference)->is_assignable_from(field_type.type_class)) {
+ hint = PROPERTY_HINT_RESOURCE_TYPE;
+ hint_string = NATIVE_GDMONOCLASS_NAME(field_type.type_class);
+ } else {
+ hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
+ hint_string = CACHED_FIELD(ExportAttribute, hint_string)->get_string_value(attr);
+ }
- PropertyInfo prop_info = PropertyInfo(type, name, PropertyHint(hint), hint_string, PropertyUsageFlags(usage));
+ PropertyInfo prop_info = PropertyInfo(type, name, hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
member_info[cname] = prop_info;
exported_members_cache.push_back(prop_info);
@@ -1334,6 +1455,34 @@ void CSharpScript::_resource_path_changed() {
}
}
+bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
+
+ if (p_name == CSharpLanguage::singleton->string_names._script_source) {
+
+ r_ret = get_source_code();
+ return true;
+ }
+
+ return false;
+}
+
+bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) {
+
+ if (p_name == CSharpLanguage::singleton->string_names._script_source) {
+
+ set_source_code(p_value);
+ reload();
+ return true;
+ }
+
+ return false;
+}
+
+void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const {
+
+ p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+}
+
void CSharpScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new"));
@@ -1392,12 +1541,15 @@ bool CSharpScript::can_instance() const {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
- if (_create_project_solution_if_needed()) {
- CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
- "Compile",
- ProjectSettings::get_singleton()->globalize_path(get_path()));
- } else {
- ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created.");
+
+ if (get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted...
+ if (_create_project_solution_if_needed()) {
+ CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
+ "Compile",
+ ProjectSettings::get_singleton()->globalize_path(get_path()));
+ } else {
+ ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created.");
+ }
}
}
#endif
@@ -1647,11 +1799,6 @@ Error CSharpScript::reload(bool p_keep_state) {
return ERR_FILE_MISSING_DEPENDENCIES;
}
-String CSharpScript::get_node_type() const {
-
- return ""; // ?
-}
-
ScriptLanguage *CSharpScript::get_language() const {
return CSharpLanguage::get_singleton();
@@ -1679,16 +1826,6 @@ void CSharpScript::update_exports() {
#ifdef TOOLS_ENABLED
_update_exports();
-
- if (placeholders.size()) {
- Map<StringName, Variant> values;
- List<PropertyInfo> propnames;
- _update_exports_values(values, propnames);
-
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->update(propnames, values);
- }
- }
#endif
}
@@ -1915,9 +2052,10 @@ bool ResourceFormatSaverCSharpScript::recognize(const RES &p_resource) const {
CSharpLanguage::StringNameCache::StringNameCache() {
- _awaited_signal_callback = StaticCString::create("_AwaitedSignalCallback");
+ _signal_callback = StaticCString::create("_signal_callback");
_set = StaticCString::create("_set");
_get = StaticCString::create("_get");
_notification = StaticCString::create("_notification");
+ _script_source = StaticCString::create("script/source");
dotctor = StaticCString::create(".ctor");
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 3fcc3bdf04..255665b495 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -116,6 +116,9 @@ protected:
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
virtual void _resource_path_changed();
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ bool _set(const StringName &p_name, const Variant &p_value);
+ void _get_property_list(List<PropertyInfo> *p_properties) const;
public:
virtual bool can_instance() const;
@@ -138,7 +141,6 @@ public:
virtual bool is_tool() const { return tool; }
virtual Ref<Script> get_base_script() const;
- virtual String get_node_type() const;
virtual ScriptLanguage *get_language() const;
/* TODO */ virtual void get_script_method_list(List<MethodInfo> *p_list) const {}
@@ -225,23 +227,26 @@ class CSharpLanguage : public ScriptLanguage {
struct StringNameCache {
- StringName _awaited_signal_callback;
+ StringName _signal_callback;
StringName _set;
StringName _get;
StringName _notification;
+ StringName _script_source;
StringName dotctor; // .ctor
StringNameCache();
};
- StringNameCache string_names;
-
int lang_idx;
public:
+ StringNameCache string_names;
+
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
void set_language_index(int p_idx);
+ _FORCE_INLINE_ const StringNameCache &get_string_names() { return string_names; }
+
_FORCE_INLINE_ static CSharpLanguage *get_singleton() { return singleton; }
bool debug_break(const String &p_error, bool p_allow_continue = true);
@@ -265,12 +270,16 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool is_using_templates();
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
/* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; }
virtual Script *create_script() const;
virtual bool has_named_classes() const;
+ virtual bool supports_builtin_mode() const;
/* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; }
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
/* TODO? */ Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { return ERR_UNAVAILABLE; }
+ virtual String _get_indentation() const;
/* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {}
/* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {}
diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
index 5544233eb7..04da0600cc 100644
--- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs
@@ -4,6 +4,7 @@ using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Build.Framework;
@@ -12,22 +13,27 @@ namespace GodotSharpTools.Build
public class BuildInstance : IDisposable
{
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_BuildInstance_ExitCallback(string solution, string config, int exitCode);
+ private extern static void godot_icall_BuildInstance_ExitCallback(string solution, string config, int exitCode);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_BuildInstance_get_MSBuildPath();
+ private extern static void godot_icall_BuildInstance_get_MSBuildInfo(ref string msbuildPath, ref string frameworkPath);
- private static string MSBuildPath
+ private struct MSBuildInfo
{
- get
- {
- string ret = godot_icall_BuildInstance_get_MSBuildPath();
+ public string path;
+ public string frameworkPathOverride;
+ }
- if (ret == null)
- throw new FileNotFoundException("Cannot find the MSBuild executable.");
+ private static MSBuildInfo GetMSBuildInfo()
+ {
+ MSBuildInfo msbuildInfo = new MSBuildInfo();
- return ret;
- }
+ godot_icall_BuildInstance_get_MSBuildInfo(ref msbuildInfo.path, ref msbuildInfo.frameworkPathOverride);
+
+ if (msbuildInfo.path == null)
+ throw new FileNotFoundException("Cannot find the MSBuild executable.");
+
+ return msbuildInfo;
}
private string solution;
@@ -48,9 +54,19 @@ namespace GodotSharpTools.Build
public bool Build(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null)
{
- string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customProperties);
+ MSBuildInfo msbuildInfo = GetMSBuildInfo();
+
+ List<string> customPropertiesList = new List<string>();
+
+ if (customProperties != null)
+ customPropertiesList.AddRange(customProperties);
+
+ if (msbuildInfo.frameworkPathOverride != null)
+ customPropertiesList.Add("FrameworkPathOverride=" + msbuildInfo.frameworkPathOverride);
- ProcessStartInfo startInfo = new ProcessStartInfo(MSBuildPath, compilerArgs);
+ string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList);
+
+ ProcessStartInfo startInfo = new ProcessStartInfo(msbuildInfo.path, compilerArgs);
// No console output, thanks
startInfo.RedirectStandardOutput = true;
@@ -82,9 +98,19 @@ namespace GodotSharpTools.Build
if (process != null)
throw new InvalidOperationException("Already in use");
- string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customProperties);
+ MSBuildInfo msbuildInfo = GetMSBuildInfo();
+
+ List<string> customPropertiesList = new List<string>();
+
+ if (customProperties != null)
+ customPropertiesList.AddRange(customProperties);
+
+ if (msbuildInfo.frameworkPathOverride.Length > 0)
+ customPropertiesList.Add("FrameworkPathOverride=" + msbuildInfo.frameworkPathOverride);
- ProcessStartInfo startInfo = new ProcessStartInfo("msbuild", compilerArgs);
+ string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList);
+
+ ProcessStartInfo startInfo = new ProcessStartInfo(msbuildInfo.path, compilerArgs);
// No console output, thanks
startInfo.RedirectStandardOutput = true;
@@ -101,10 +127,13 @@ namespace GodotSharpTools.Build
process.Start();
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+
return true;
}
- private string BuildArguments(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties)
+ private string BuildArguments(string loggerAssemblyPath, string loggerOutputDir, List<string> customProperties)
{
string arguments = string.Format(@"""{0}"" /v:normal /t:Build ""/p:{1}"" ""/l:{2},{3};{4}""",
solution,
@@ -114,12 +143,9 @@ namespace GodotSharpTools.Build
loggerOutputDir
);
- if (customProperties != null)
+ foreach (string customProperty in customProperties)
{
- foreach (string customProperty in customProperties)
- {
- arguments += " /p:" + customProperty;
- }
+ arguments += " \"/p:" + customProperty + "\"";
}
return arguments;
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln b/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln
index 7eabcdff5d..5f7d0e8a39 100644
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln
+++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln
@@ -1,17 +1,17 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotSharpTools", "GodotSharpTools.csproj", "{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotSharpTools", "GodotSharpTools.csproj", "{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 704910c5b9..eb504ec021 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -108,36 +108,6 @@ const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in
bool BindingsGenerator::verbose_output = false;
-static bool is_csharp_keyword(const String &p_name) {
-
- // Reserved keywords
-
- return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" ||
- p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" ||
- p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" ||
- p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" ||
- p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" ||
- p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" ||
- p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" ||
- p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" ||
- p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" ||
- p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" ||
- p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" ||
- p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" ||
- p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" ||
- p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" ||
- p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" ||
- p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" ||
- p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" ||
- p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" ||
- p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while";
-}
-
-inline static String escape_csharp_keyword(const String &p_name) {
-
- return is_csharp_keyword(p_name) ? "@" + p_name : p_name;
-}
-
static String snake_to_pascal_case(const String &p_identifier) {
String ret;
@@ -468,6 +438,9 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo
return sln_error;
}
+ if (verbose_output)
+ OS::get_singleton()->print("The solution and C# project for the Core API was generated successfully\n");
+
return OK;
}
@@ -560,6 +533,9 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
return sln_error;
}
+ if (verbose_output)
+ OS::get_singleton()->print("The solution and C# project for the Editor API was generated successfully\n");
+
return OK;
}
@@ -567,8 +543,6 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
// e.g.: warning CS0108: 'SpriteBase3D.FLAG_MAX' hides inherited member 'GeometryInstance.FLAG_MAX'. Use the new keyword if hiding was intended.
Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const String &p_output_file) {
- int method_bind_count = 0;
-
bool is_derived_type = itype.base_name.length();
List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
@@ -578,51 +552,51 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor");
- List<String> cs_file;
+ List<String> output;
- cs_file.push_back("using System;\n"); // IntPtr
+ output.push_back("using System;\n"); // IntPtr
if (itype.requires_collections)
- cs_file.push_back("using System.Collections.Generic;\n"); // Dictionary
+ output.push_back("using System.Collections.Generic;\n"); // Dictionary
- cs_file.push_back("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
+ output.push_back("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
const DocData::ClassDoc *class_doc = itype.class_doc;
if (class_doc && class_doc->description.size()) {
- cs_file.push_back(INDENT1 "/// <summary>\n");
+ output.push_back(INDENT1 "/// <summary>\n");
Vector<String> description_lines = class_doc->description.split("\n");
for (int i = 0; i < description_lines.size(); i++) {
if (description_lines[i].size()) {
- cs_file.push_back(INDENT1 "/// ");
- cs_file.push_back(description_lines[i].strip_edges().xml_escape());
- cs_file.push_back("\n");
+ output.push_back(INDENT1 "/// ");
+ output.push_back(description_lines[i].strip_edges().xml_escape());
+ output.push_back("\n");
}
}
- cs_file.push_back(INDENT1 "/// </summary>\n");
+ output.push_back(INDENT1 "/// </summary>\n");
}
- cs_file.push_back(INDENT1 "public ");
- cs_file.push_back(itype.is_singleton ? "static class " : "class ");
- cs_file.push_back(itype.proxy_name);
+ output.push_back(INDENT1 "public ");
+ output.push_back(itype.is_singleton ? "static class " : "class ");
+ output.push_back(itype.proxy_name);
if (itype.is_singleton || !itype.is_object_type) {
- cs_file.push_back("\n");
+ output.push_back("\n");
} else if (!is_derived_type) {
- cs_file.push_back(" : IDisposable\n");
+ output.push_back(" : IDisposable\n");
} else if (obj_types.has(itype.base_name)) {
- cs_file.push_back(" : ");
- cs_file.push_back(obj_types[itype.base_name].proxy_name);
- cs_file.push_back("\n");
+ output.push_back(" : ");
+ output.push_back(obj_types[itype.base_name].proxy_name);
+ output.push_back("\n");
} else {
- ERR_PRINTS("Base type ' " + itype.base_name + "' does not exist");
+ ERR_PRINTS("Base type '" + itype.base_name + "' does not exist, for class " + itype.name);
return ERR_INVALID_DATA;
}
- cs_file.push_back(INDENT1 "{");
+ output.push_back(INDENT1 "{");
if (class_doc) {
@@ -632,270 +606,165 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
const DocData::ConstantDoc &const_doc = class_doc->constants[i];
if (const_doc.description.size()) {
- cs_file.push_back(MEMBER_BEGIN "/// <summary>\n");
+ output.push_back(MEMBER_BEGIN "/// <summary>\n");
Vector<String> description_lines = const_doc.description.split("\n");
for (int i = 0; i < description_lines.size(); i++) {
if (description_lines[i].size()) {
- cs_file.push_back(INDENT2 "/// ");
- cs_file.push_back(description_lines[i].strip_edges().xml_escape());
- cs_file.push_back("\n");
+ output.push_back(INDENT2 "/// ");
+ output.push_back(description_lines[i].strip_edges().xml_escape());
+ output.push_back("\n");
}
}
- cs_file.push_back(INDENT2 "/// </summary>");
+ output.push_back(INDENT2 "/// </summary>");
}
- cs_file.push_back(MEMBER_BEGIN "public const int ");
- cs_file.push_back(const_doc.name);
- cs_file.push_back(" = ");
- cs_file.push_back(const_doc.value);
- cs_file.push_back(";");
+ output.push_back(MEMBER_BEGIN "public const int ");
+ output.push_back(const_doc.name);
+ output.push_back(" = ");
+ output.push_back(const_doc.value);
+ output.push_back(";");
}
if (class_doc->constants.size())
- cs_file.push_back("\n");
+ output.push_back("\n");
// Add properties
- const Vector<DocData::PropertyDoc> &properties = itype.class_doc->properties;
+ const Vector<DocData::PropertyDoc> &properties = class_doc->properties;
for (int i = 0; i < properties.size(); i++) {
const DocData::PropertyDoc &prop_doc = properties[i];
-
- const MethodInterface *setter = itype.find_method_by_name(prop_doc.setter);
-
- // Search it in base types too
- const TypeInterface *current_type = &itype;
- while (!setter && current_type->base_name.length()) {
- Map<String, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name);
- ERR_FAIL_NULL_V(base_match, ERR_BUG);
- current_type = &base_match->get();
- setter = current_type->find_method_by_name(prop_doc.setter);
- }
-
- const MethodInterface *getter = itype.find_method_by_name(prop_doc.getter);
-
- // Search it in base types too
- current_type = &itype;
- while (!getter && current_type->base_name.length()) {
- Map<String, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name);
- ERR_FAIL_NULL_V(base_match, ERR_BUG);
- current_type = &base_match->get();
- getter = current_type->find_method_by_name(prop_doc.getter);
+ Error prop_err = _generate_cs_property(itype, prop_doc, output);
+ if (prop_err != OK) {
+ ERR_EXPLAIN("Failed to generate property '" + prop_doc.name + "' for class '" + itype.name + "'");
+ ERR_FAIL_V(prop_err);
}
-
- ERR_FAIL_COND_V(!setter && !getter, ERR_BUG);
-
- bool is_valid = false;
- int prop_index = ClassDB::get_property_index(itype.name, prop_doc.name, &is_valid);
- ERR_FAIL_COND_V(!is_valid, ERR_BUG);
-
- if (setter) {
- int setter_argc = prop_index != -1 ? 2 : 1;
- ERR_FAIL_COND_V(setter->arguments.size() != setter_argc, ERR_BUG);
- }
-
- if (getter) {
- int getter_argc = prop_index != -1 ? 1 : 0;
- ERR_FAIL_COND_V(getter->arguments.size() != getter_argc, ERR_BUG);
- }
-
- if (getter && setter) {
- ERR_FAIL_COND_V(getter->return_type != setter->arguments.back()->get().type, ERR_BUG);
- }
-
- // Let's not trust PropertyDoc::type
- String proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
-
- const TypeInterface *prop_itype = _get_type_by_name_or_null(proptype_name);
- if (!prop_itype) {
- // Try with underscore prefix
- prop_itype = _get_type_by_name_or_null("_" + proptype_name);
- }
-
- ERR_FAIL_NULL_V(prop_itype, ERR_BUG);
-
- String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(prop_doc.name));
-
- // Prevent property and enclosing type from sharing the same name
- if (prop_proxy_name == itype.proxy_name) {
- if (verbose_output) {
- WARN_PRINTS("Name of property `" + prop_proxy_name + "` is ambiguous with the name of its class `" +
- itype.proxy_name + "`. Renaming property to `" + prop_proxy_name + "_`");
- }
-
- prop_proxy_name += "_";
- }
-
- if (prop_doc.description.size()) {
- cs_file.push_back(MEMBER_BEGIN "/// <summary>\n");
-
- Vector<String> description_lines = prop_doc.description.split("\n");
-
- for (int i = 0; i < description_lines.size(); i++) {
- if (description_lines[i].size()) {
- cs_file.push_back(INDENT2 "/// ");
- cs_file.push_back(description_lines[i].strip_edges().xml_escape());
- cs_file.push_back("\n");
- }
- }
-
- cs_file.push_back(INDENT2 "/// </summary>");
- }
-
- cs_file.push_back(MEMBER_BEGIN "public ");
-
- if (itype.is_singleton)
- cs_file.push_back("static ");
-
- cs_file.push_back(prop_itype->cs_type);
- cs_file.push_back(" ");
- cs_file.push_back(prop_proxy_name.replace("/", "__"));
- cs_file.push_back("\n" INDENT2 OPEN_BLOCK);
-
- if (getter) {
- cs_file.push_back(INDENT3 "get\n" OPEN_BLOCK_L3);
- cs_file.push_back("return ");
- cs_file.push_back(getter->proxy_name + "(");
- if (prop_index != -1)
- cs_file.push_back(itos(prop_index));
- cs_file.push_back(");\n" CLOSE_BLOCK_L3);
- }
-
- if (setter) {
- cs_file.push_back(INDENT3 "set\n" OPEN_BLOCK_L3);
- cs_file.push_back(setter->proxy_name + "(");
- if (prop_index != -1)
- cs_file.push_back(itos(prop_index) + ", ");
- cs_file.push_back("value);\n" CLOSE_BLOCK_L3);
- }
-
- cs_file.push_back(CLOSE_BLOCK_L2);
}
if (class_doc->properties.size())
- cs_file.push_back("\n");
+ output.push_back("\n");
}
if (!itype.is_object_type) {
- cs_file.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"" + itype.name + "\";\n");
- cs_file.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
- cs_file.push_back(MEMBER_BEGIN "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
+ output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"" + itype.name + "\";\n");
+ output.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
+ output.push_back(MEMBER_BEGIN "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
- cs_file.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back(" instance)\n" OPEN_BLOCK_L2 "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(");
+ output.push_back(itype.proxy_name);
+ output.push_back(" instance)\n" OPEN_BLOCK_L2 "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
// Add Destructor
- cs_file.push_back(MEMBER_BEGIN "~");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "~");
+ output.push_back(itype.proxy_name);
+ output.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
// Add the Dispose from IDisposable
- cs_file.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
// Add the virtual Dispose
- cs_file.push_back(MEMBER_BEGIN "public virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
- "if (disposed) return;\n" INDENT3
- "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3 "NativeCalls.godot_icall_");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("_Dtor(" BINDINGS_PTR_FIELD ");\n" INDENT5 BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" CLOSE_BLOCK_L3 INDENT3
- "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
-
- cs_file.push_back(MEMBER_BEGIN "internal ");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("(IntPtr " BINDINGS_PTR_FIELD ")\n" OPEN_BLOCK_L2 "this." BINDINGS_PTR_FIELD " = " BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
-
- cs_file.push_back(MEMBER_BEGIN "public bool HasValidHandle()\n" OPEN_BLOCK_L2
- "return " BINDINGS_PTR_FIELD " == IntPtr.Zero;\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
+ "if (disposed) return;\n" INDENT3
+ "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3 "NativeCalls.godot_icall_");
+ output.push_back(itype.proxy_name);
+ output.push_back("_Dtor(" BINDINGS_PTR_FIELD ");\n" INDENT5 BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" CLOSE_BLOCK_L3 INDENT3
+ "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
+
+ output.push_back(MEMBER_BEGIN "internal ");
+ output.push_back(itype.proxy_name);
+ output.push_back("(IntPtr " BINDINGS_PTR_FIELD ")\n" OPEN_BLOCK_L2 "this." BINDINGS_PTR_FIELD " = " BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
+
+ output.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2
+ "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2);
} else if (itype.is_singleton) {
// Add the type name and the singleton pointer as static fields
- cs_file.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
- cs_file.push_back(itype.name);
- cs_file.push_back("\";\n");
+ output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
+ output.push_back(itype.name);
+ output.push_back("\";\n");
- cs_file.push_back(INDENT2 "internal static IntPtr " BINDINGS_PTR_FIELD " = ");
- cs_file.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS);
- cs_file.push_back("." ICALL_PREFIX);
- cs_file.push_back(itype.name);
- cs_file.push_back(SINGLETON_ICALL_SUFFIX "();\n");
+ output.push_back(INDENT2 "internal static IntPtr " BINDINGS_PTR_FIELD " = ");
+ output.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS);
+ output.push_back("." ICALL_PREFIX);
+ output.push_back(itype.name);
+ output.push_back(SINGLETON_ICALL_SUFFIX "();\n");
} else {
// Add member fields
- cs_file.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
- cs_file.push_back(itype.name);
- cs_file.push_back("\";\n");
+ output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
+ output.push_back(itype.name);
+ output.push_back("\";\n");
// Only the base class stores the pointer to the native object
// This pointer is expected to be and must be of type Object*
if (!is_derived_type) {
- cs_file.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
- cs_file.push_back(INDENT2 "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
- cs_file.push_back(INDENT2 "internal bool " CS_FIELD_MEMORYOWN ";\n");
+ output.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
+ output.push_back(INDENT2 "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
+ output.push_back(INDENT2 "internal bool " CS_FIELD_MEMORYOWN ";\n");
}
// Add default constructor
if (itype.is_instantiable) {
- cs_file.push_back(MEMBER_BEGIN "public ");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("() : this(");
- cs_file.push_back(itype.memory_own ? "true" : "false");
+ output.push_back(MEMBER_BEGIN "public ");
+ output.push_back(itype.proxy_name);
+ output.push_back("() : this(");
+ output.push_back(itype.memory_own ? "true" : "false");
// The default constructor may also be called by the engine when instancing existing native objects
// The engine will initialize the pointer field of the managed side before calling the constructor
// This is why we only allocate a new native object from the constructor if the pointer field is not set
- cs_file.push_back(")\n" OPEN_BLOCK_L2 "if (" BINDINGS_PTR_FIELD " == IntPtr.Zero)\n" INDENT4 BINDINGS_PTR_FIELD " = ");
- cs_file.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS);
- cs_file.push_back("." + ctor_method);
- cs_file.push_back("(this);\n" CLOSE_BLOCK_L2);
+ output.push_back(")\n" OPEN_BLOCK_L2 "if (" BINDINGS_PTR_FIELD " == IntPtr.Zero)\n" INDENT4 BINDINGS_PTR_FIELD " = ");
+ output.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS);
+ output.push_back("." + ctor_method);
+ output.push_back("(this);\n" CLOSE_BLOCK_L2);
} else {
// Hide the constructor
- cs_file.push_back(MEMBER_BEGIN "internal ");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("() {}\n");
+ output.push_back(MEMBER_BEGIN "internal ");
+ output.push_back(itype.proxy_name);
+ output.push_back("() {}\n");
}
// Add.. em.. trick constructor. Sort of.
- cs_file.push_back(MEMBER_BEGIN "internal ");
- cs_file.push_back(itype.proxy_name);
+ output.push_back(MEMBER_BEGIN "internal ");
+ output.push_back(itype.proxy_name);
if (is_derived_type) {
- cs_file.push_back("(bool " CS_FIELD_MEMORYOWN ") : base(" CS_FIELD_MEMORYOWN ") {}\n");
+ output.push_back("(bool " CS_FIELD_MEMORYOWN ") : base(" CS_FIELD_MEMORYOWN ") {}\n");
} else {
- cs_file.push_back("(bool " CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L2
- "this." CS_FIELD_MEMORYOWN " = " CS_FIELD_MEMORYOWN ";\n" CLOSE_BLOCK_L2);
+ output.push_back("(bool " CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L2
+ "this." CS_FIELD_MEMORYOWN " = " CS_FIELD_MEMORYOWN ";\n" CLOSE_BLOCK_L2);
}
// Add methods
if (!is_derived_type) {
- cs_file.push_back(MEMBER_BEGIN "public bool HasValidHandle()\n" OPEN_BLOCK_L2
- "return " BINDINGS_PTR_FIELD " == IntPtr.Zero;\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2
+ "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2);
- cs_file.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(Object instance)\n" OPEN_BLOCK_L2
- "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(Object instance)\n" OPEN_BLOCK_L2
+ "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
}
if (!is_derived_type) {
// Add destructor
- cs_file.push_back(MEMBER_BEGIN "~");
- cs_file.push_back(itype.proxy_name);
- cs_file.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "~");
+ output.push_back(itype.proxy_name);
+ output.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
// Add the Dispose from IDisposable
- cs_file.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
// Add the virtual Dispose
- cs_file.push_back(MEMBER_BEGIN "public virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
- "if (disposed) return;\n" INDENT3
- "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3
- "if (" CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L4 CS_FIELD_MEMORYOWN
- " = false;\n" INDENT5 CS_CLASS_NATIVECALLS "." ICALL_OBJECT_DTOR
- "(" BINDINGS_PTR_FIELD ");\n" INDENT5 BINDINGS_PTR_FIELD
- " = IntPtr.Zero;\n" CLOSE_BLOCK_L4 CLOSE_BLOCK_L3 INDENT3
- "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
+ "if (disposed) return;\n" INDENT3
+ "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3
+ "if (" CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L4 CS_FIELD_MEMORYOWN
+ " = false;\n" INDENT5 CS_CLASS_NATIVECALLS "." ICALL_OBJECT_DTOR
+ "(" BINDINGS_PTR_FIELD ");\n" INDENT5 BINDINGS_PTR_FIELD
+ " = IntPtr.Zero;\n" CLOSE_BLOCK_L4 CLOSE_BLOCK_L3 INDENT3
+ "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
Map<String, TypeInterface>::Element *array_itype = builtin_types.find("Array");
@@ -904,416 +773,390 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
return ERR_BUG;
}
- cs_file.push_back(MEMBER_BEGIN "private void _AwaitedSignalCallback(");
- cs_file.push_back(array_itype->get().cs_type);
- cs_file.push_back(" args, SignalAwaiter awaiter)\n" OPEN_BLOCK_L2 "awaiter.SignalCallback(args);\n" CLOSE_BLOCK_L2);
-
Map<String, TypeInterface>::Element *object_itype = obj_types.find("Object");
if (!object_itype) {
- ERR_PRINT("BUG: Array type interface not found!");
+ ERR_PRINT("BUG: Object type interface not found!");
return ERR_BUG;
}
- cs_file.push_back(MEMBER_BEGIN "public " CS_CLASS_SIGNALAWAITER " ToSignal(");
- cs_file.push_back(object_itype->get().cs_type);
- cs_file.push_back(" source, string signal)\n" OPEN_BLOCK_L2
- "return new " CS_CLASS_SIGNALAWAITER "(source, signal, this);\n" CLOSE_BLOCK_L2);
+ output.push_back(MEMBER_BEGIN "public " CS_CLASS_SIGNALAWAITER " ToSignal(");
+ output.push_back(object_itype->get().cs_type);
+ output.push_back(" source, string signal)\n" OPEN_BLOCK_L2
+ "return new " CS_CLASS_SIGNALAWAITER "(source, signal, this);\n" CLOSE_BLOCK_L2);
}
}
Map<String, String>::Element *extra_member = extra_members.find(itype.name);
if (extra_member)
- cs_file.push_back(extra_member->get());
+ output.push_back(extra_member->get());
+ int method_bind_count = 0;
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
+ Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output);
+ if (method_err != OK) {
+ ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
+ ERR_FAIL_V(method_err);
+ }
+ }
- const TypeInterface *return_type = _get_type_by_name_or_placeholder(imethod.return_type);
+ if (itype.is_singleton) {
+ InternalCall singleton_icall = InternalCall(itype.api_type, ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX, "IntPtr");
- String method_bind_field = "method_bind_" + itos(method_bind_count);
+ if (!find_icall_by_name(singleton_icall.name, custom_icalls))
+ custom_icalls.push_back(singleton_icall);
+ }
- String icall_params = method_bind_field + ", " + sformat(itype.cs_in, "this");
- String arguments_sig;
- String cs_in_statements;
+ if (itype.is_instantiable) {
+ InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
- List<String> default_args_doc;
+ if (!find_icall_by_name(ctor_icall.name, custom_icalls))
+ custom_icalls.push_back(ctor_icall);
+ }
- // Retrieve information from the arguments
- for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
- const ArgumentInterface &iarg = F->get();
- const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
+ output.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
- // Add the current arguments to the signature
- // If the argument has a default value which is not a constant, we will make it Nullable
- {
- if (F != imethod.arguments.front())
- arguments_sig += ", ";
+ return _save_file(p_output_file, output);
+}
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
- arguments_sig += "Nullable<";
+Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInterface &p_itype, const DocData::PropertyDoc &p_prop_doc, List<String> &p_output) {
- arguments_sig += arg_type->cs_type;
+ const MethodInterface *setter = p_itype.find_method_by_name(p_prop_doc.setter);
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
- arguments_sig += "> ";
- else
- arguments_sig += " ";
+ // Search it in base types too
+ const TypeInterface *current_type = &p_itype;
+ while (!setter && current_type->base_name.length()) {
+ Map<String, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name);
+ ERR_FAIL_NULL_V(base_match, ERR_BUG);
+ current_type = &base_match->get();
+ setter = current_type->find_method_by_name(p_prop_doc.setter);
+ }
- arguments_sig += iarg.name;
+ const MethodInterface *getter = p_itype.find_method_by_name(p_prop_doc.getter);
- if (iarg.default_argument.size()) {
- if (iarg.def_param_mode != ArgumentInterface::CONSTANT)
- arguments_sig += " = null";
- else
- arguments_sig += " = " + sformat(iarg.default_argument, arg_type->cs_type);
- }
- }
+ // Search it in base types too
+ current_type = &p_itype;
+ while (!getter && current_type->base_name.length()) {
+ Map<String, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name);
+ ERR_FAIL_NULL_V(base_match, ERR_BUG);
+ current_type = &base_match->get();
+ getter = current_type->find_method_by_name(p_prop_doc.getter);
+ }
- icall_params += ", ";
+ ERR_FAIL_COND_V(!setter && !getter, ERR_BUG);
- if (iarg.default_argument.size() && iarg.def_param_mode != ArgumentInterface::CONSTANT) {
- // The default value of an argument must be constant. Otherwise we make it Nullable and do the following:
- // Type arg_in = arg.HasValue ? arg.Value : <non-const default value>;
- String arg_in = iarg.name;
- arg_in += "_in";
+ bool is_valid = false;
+ int prop_index = ClassDB::get_property_index(p_itype.name, p_prop_doc.name, &is_valid);
+ ERR_FAIL_COND_V(!is_valid, ERR_BUG);
- cs_in_statements += arg_type->cs_type;
- cs_in_statements += " ";
- cs_in_statements += arg_in;
- cs_in_statements += " = ";
- cs_in_statements += iarg.name;
+ if (setter) {
+ int setter_argc = prop_index != -1 ? 2 : 1;
+ ERR_FAIL_COND_V(setter->arguments.size() != setter_argc, ERR_BUG);
+ }
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
- cs_in_statements += ".HasValue ? ";
- else
- cs_in_statements += " != null ? ";
+ if (getter) {
+ int getter_argc = prop_index != -1 ? 1 : 0;
+ ERR_FAIL_COND_V(getter->arguments.size() != getter_argc, ERR_BUG);
+ }
- cs_in_statements += iarg.name;
+ if (getter && setter) {
+ ERR_FAIL_COND_V(getter->return_type != setter->arguments.back()->get().type, ERR_BUG);
+ }
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
- cs_in_statements += ".Value : ";
- else
- cs_in_statements += " : ";
+ // Let's not trust PropertyDoc::type
+ String proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
- String def_arg = sformat(iarg.default_argument, arg_type->cs_type);
+ const TypeInterface *prop_itype = _get_type_by_name_or_null(proptype_name);
+ if (!prop_itype) {
+ // Try with underscore prefix
+ prop_itype = _get_type_by_name_or_null("_" + proptype_name);
+ }
- cs_in_statements += def_arg;
- cs_in_statements += ";\n" INDENT3;
+ ERR_FAIL_NULL_V(prop_itype, ERR_BUG);
- icall_params += arg_type->cs_in.empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
+ String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(p_prop_doc.name));
- default_args_doc.push_back(INDENT2 "/// <param name=\"" + iarg.name + "\">If the param is null, then the default value is " + def_arg + "</param>\n");
- } else {
- icall_params += arg_type->cs_in.empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
- }
+ // Prevent property and enclosing type from sharing the same name
+ if (prop_proxy_name == p_itype.proxy_name) {
+ if (verbose_output) {
+ WARN_PRINTS("Name of property `" + prop_proxy_name + "` is ambiguous with the name of its class `" +
+ p_itype.proxy_name + "`. Renaming property to `" + prop_proxy_name + "_`");
}
- // Generate method
- {
- if (!imethod.is_virtual && !imethod.requires_object_call) {
- cs_file.push_back(MEMBER_BEGIN "private ");
- cs_file.push_back(itype.is_singleton ? "static IntPtr " : "IntPtr ");
- cs_file.push_back(method_bind_field + " = " CS_CLASS_NATIVECALLS "." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
- cs_file.push_back(imethod.name);
- cs_file.push_back("\");\n");
- }
+ prop_proxy_name += "_";
+ }
- if (imethod.method_doc && imethod.method_doc->description.size()) {
- cs_file.push_back(MEMBER_BEGIN "/// <summary>\n");
+ if (p_prop_doc.description.size()) {
+ p_output.push_back(MEMBER_BEGIN "/// <summary>\n");
- Vector<String> description_lines = imethod.method_doc->description.split("\n");
+ Vector<String> description_lines = p_prop_doc.description.split("\n");
- for (int i = 0; i < description_lines.size(); i++) {
- if (description_lines[i].size()) {
- cs_file.push_back(INDENT2 "/// ");
- cs_file.push_back(description_lines[i].strip_edges().xml_escape());
- cs_file.push_back("\n");
- }
- }
+ for (int i = 0; i < description_lines.size(); i++) {
+ if (description_lines[i].size()) {
+ p_output.push_back(INDENT2 "/// ");
+ p_output.push_back(description_lines[i].strip_edges().xml_escape());
+ p_output.push_back("\n");
+ }
+ }
- for (List<String>::Element *E = default_args_doc.front(); E; E = E->next()) {
- cs_file.push_back(E->get().xml_escape());
- }
+ p_output.push_back(INDENT2 "/// </summary>");
+ }
- cs_file.push_back(INDENT2 "/// </summary>");
- }
+ p_output.push_back(MEMBER_BEGIN "public ");
- if (!imethod.is_internal) {
- cs_file.push_back(MEMBER_BEGIN "[GodotMethod(\"");
- cs_file.push_back(imethod.name);
- cs_file.push_back("\")]");
- }
+ if (p_itype.is_singleton)
+ p_output.push_back("static ");
- cs_file.push_back(MEMBER_BEGIN);
- cs_file.push_back(imethod.is_internal ? "internal " : "public ");
+ p_output.push_back(prop_itype->cs_type);
+ p_output.push_back(" ");
+ p_output.push_back(prop_proxy_name.replace("/", "__"));
+ p_output.push_back("\n" INDENT2 OPEN_BLOCK);
- if (itype.is_singleton) {
- cs_file.push_back("static ");
- } else if (imethod.is_virtual) {
- cs_file.push_back("virtual ");
- }
+ if (getter) {
+ p_output.push_back(INDENT3 "get\n" OPEN_BLOCK_L3);
+ p_output.push_back("return ");
+ p_output.push_back(getter->proxy_name + "(");
+ if (prop_index != -1)
+ p_output.push_back(itos(prop_index));
+ p_output.push_back(");\n" CLOSE_BLOCK_L3);
+ }
- cs_file.push_back(return_type->cs_type + " ");
- cs_file.push_back(imethod.proxy_name + "(");
- cs_file.push_back(arguments_sig + ")\n" OPEN_BLOCK_L2);
+ if (setter) {
+ p_output.push_back(INDENT3 "set\n" OPEN_BLOCK_L3);
+ p_output.push_back(setter->proxy_name + "(");
+ if (prop_index != -1)
+ p_output.push_back(itos(prop_index) + ", ");
+ p_output.push_back("value);\n" CLOSE_BLOCK_L3);
+ }
- if (imethod.is_virtual) {
- // Godot virtual method must be overridden, therefore we return a default value by default.
+ p_output.push_back(CLOSE_BLOCK_L2);
- if (return_type->name == "void") {
- cs_file.push_back("return;\n" CLOSE_BLOCK_L2);
- } else {
- cs_file.push_back("return default(");
- cs_file.push_back(return_type->cs_type);
- cs_file.push_back(");\n" CLOSE_BLOCK_L2);
- }
+ return OK;
+}
- continue;
- }
+Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output) {
- if (imethod.requires_object_call) {
- // Fallback to Godot's object.Call(string, params)
+ const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
- cs_file.push_back(CS_METHOD_CALL "(\"");
- cs_file.push_back(imethod.name);
- cs_file.push_back("\"");
+ String method_bind_field = "method_bind_" + itos(p_method_bind_count);
- for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
- cs_file.push_back(", ");
- cs_file.push_back(F->get().name);
- }
+ String icall_params = method_bind_field + ", " + sformat(p_itype.cs_in, "this");
+ String arguments_sig;
+ String cs_in_statements;
- cs_file.push_back(");\n" CLOSE_BLOCK_L2);
+ List<String> default_args_doc;
- continue;
- }
+ // Retrieve information from the arguments
+ for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
+ const ArgumentInterface &iarg = F->get();
+ const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
- const Map<const MethodInterface *, const InternalCall *>::Element *match = method_icalls_map.find(&E->get());
- ERR_FAIL_NULL_V(match, ERR_BUG);
+ // Add the current arguments to the signature
+ // If the argument has a default value which is not a constant, we will make it Nullable
+ {
+ if (F != p_imethod.arguments.front())
+ arguments_sig += ", ";
- const InternalCall *im_icall = match->value();
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ arguments_sig += "Nullable<";
- String im_call = im_icall->editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS;
- im_call += "." + im_icall->name + "(" + icall_params + ");\n";
+ arguments_sig += arg_type->cs_type;
- if (imethod.arguments.size())
- cs_file.push_back(cs_in_statements);
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ arguments_sig += "> ";
+ else
+ arguments_sig += " ";
- if (return_type->name == "void") {
- cs_file.push_back(im_call);
- } else if (return_type->cs_out.empty()) {
- cs_file.push_back("return " + im_call);
- } else {
- cs_file.push_back(return_type->im_type_out);
- cs_file.push_back(" " LOCAL_RET " = ");
- cs_file.push_back(im_call);
- cs_file.push_back(INDENT3);
- cs_file.push_back(sformat(return_type->cs_out, LOCAL_RET) + "\n");
- }
+ arguments_sig += iarg.name;
- cs_file.push_back(CLOSE_BLOCK_L2);
+ if (iarg.default_argument.size()) {
+ if (iarg.def_param_mode != ArgumentInterface::CONSTANT)
+ arguments_sig += " = null";
+ else
+ arguments_sig += " = " + sformat(iarg.default_argument, arg_type->cs_type);
+ }
}
- method_bind_count++;
- }
+ icall_params += ", ";
- if (itype.is_singleton) {
- InternalCall singleton_icall = InternalCall(itype.api_type, ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX, "IntPtr");
+ if (iarg.default_argument.size() && iarg.def_param_mode != ArgumentInterface::CONSTANT) {
+ // The default value of an argument must be constant. Otherwise we make it Nullable and do the following:
+ // Type arg_in = arg.HasValue ? arg.Value : <non-const default value>;
+ String arg_in = iarg.name;
+ arg_in += "_in";
- if (!find_icall_by_name(singleton_icall.name, custom_icalls))
- custom_icalls.push_back(singleton_icall);
- }
+ cs_in_statements += arg_type->cs_type;
+ cs_in_statements += " ";
+ cs_in_statements += arg_in;
+ cs_in_statements += " = ";
+ cs_in_statements += iarg.name;
- if (itype.is_instantiable) {
- InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ cs_in_statements += ".HasValue ? ";
+ else
+ cs_in_statements += " != null ? ";
- if (!find_icall_by_name(ctor_icall.name, custom_icalls))
- custom_icalls.push_back(ctor_icall);
- }
+ cs_in_statements += iarg.name;
- cs_file.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ cs_in_statements += ".Value : ";
+ else
+ cs_in_statements += " : ";
- return _save_file(p_output_file, cs_file);
-}
+ String def_arg = sformat(iarg.default_argument, arg_type->cs_type);
-Error BindingsGenerator::generate_glue(const String &p_output_dir) {
+ cs_in_statements += def_arg;
+ cs_in_statements += ";\n" INDENT3;
- verbose_output = true;
+ icall_params += arg_type->cs_in.empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
- bool dir_exists = DirAccess::exists(p_output_dir);
- ERR_EXPLAIN("The output directory does not exist.");
- ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
+ default_args_doc.push_back(INDENT2 "/// <param name=\"" + iarg.name + "\">If the param is null, then the default value is " + def_arg + "</param>\n");
+ } else {
+ icall_params += arg_type->cs_in.empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
+ }
+ }
- List<String> cpp_file;
+ // Generate method
+ {
+ if (!p_imethod.is_virtual && !p_imethod.requires_object_call) {
+ p_output.push_back(MEMBER_BEGIN "private ");
+ p_output.push_back(p_itype.is_singleton ? "static IntPtr " : "IntPtr ");
+ p_output.push_back(method_bind_field + " = " CS_CLASS_NATIVECALLS "." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
+ p_output.push_back(p_imethod.name);
+ p_output.push_back("\");\n");
+ }
- cpp_file.push_back("#include \"" GLUE_HEADER_FILE "\"\n"
- "\n");
+ if (p_imethod.method_doc && p_imethod.method_doc->description.size()) {
+ p_output.push_back(MEMBER_BEGIN "/// <summary>\n");
- List<const InternalCall *> generated_icall_funcs;
+ Vector<String> description_lines = p_imethod.method_doc->description.split("\n");
- for (Map<String, TypeInterface>::Element *type_elem = obj_types.front(); type_elem; type_elem = type_elem->next()) {
- const TypeInterface &itype = type_elem->get();
+ for (int i = 0; i < description_lines.size(); i++) {
+ if (description_lines[i].size()) {
+ p_output.push_back(INDENT2 "/// ");
+ p_output.push_back(description_lines[i].strip_edges().xml_escape());
+ p_output.push_back("\n");
+ }
+ }
- List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
+ for (List<String>::Element *E = default_args_doc.front(); E; E = E->next()) {
+ p_output.push_back(E->get().xml_escape());
+ }
- OS::get_singleton()->print(String("Generating " + itype.name + "...\n").utf8());
+ p_output.push_back(INDENT2 "/// </summary>");
+ }
- String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor");
+ if (!p_imethod.is_internal) {
+ p_output.push_back(MEMBER_BEGIN "[GodotMethod(\"");
+ p_output.push_back(p_imethod.name);
+ p_output.push_back("\")]");
+ }
- for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
- const MethodInterface &imethod = E->get();
+ p_output.push_back(MEMBER_BEGIN);
+ p_output.push_back(p_imethod.is_internal ? "internal " : "public ");
- if (imethod.is_virtual)
- continue;
+ if (p_itype.is_singleton) {
+ p_output.push_back("static ");
+ } else if (p_imethod.is_virtual) {
+ p_output.push_back("virtual ");
+ }
- bool ret_void = imethod.return_type == "void";
+ p_output.push_back(return_type->cs_type + " ");
+ p_output.push_back(p_imethod.proxy_name + "(");
+ p_output.push_back(arguments_sig + ")\n" OPEN_BLOCK_L2);
- const TypeInterface *return_type = _get_type_by_name_or_placeholder(imethod.return_type);
+ if (p_imethod.is_virtual) {
+ // Godot virtual method must be overridden, therefore we return a default value by default.
- String argc_str = itos(imethod.arguments.size());
+ if (return_type->name == "void") {
+ p_output.push_back("return;\n" CLOSE_BLOCK_L2);
+ } else {
+ p_output.push_back("return default(");
+ p_output.push_back(return_type->cs_type);
+ p_output.push_back(");\n" CLOSE_BLOCK_L2);
+ }
- String c_func_sig = "MethodBind* " CS_PARAM_METHODBIND ", " + itype.c_type_in + " " CS_PARAM_INSTANCE;
- String c_in_statements;
- String c_args_var_content;
+ return OK; // Won't increment method bind count
+ }
- // Get arguments information
- int i = 0;
- for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
- const ArgumentInterface &iarg = F->get();
- const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
+ if (p_imethod.requires_object_call) {
+ // Fallback to Godot's object.Call(string, params)
- String c_param_name = "arg" + itos(i + 1);
+ p_output.push_back(CS_METHOD_CALL "(\"");
+ p_output.push_back(p_imethod.name);
+ p_output.push_back("\"");
- if (imethod.is_vararg) {
- if (i < imethod.arguments.size() - 1) {
- c_in_statements += sformat(arg_type->c_in.size() ? arg_type->c_in : TypeInterface::DEFAULT_VARARG_C_IN, "Variant", c_param_name);
- c_in_statements += "\t" C_LOCAL_PTRCALL_ARGS ".set(0, ";
- c_in_statements += sformat("&%s_in", c_param_name);
- c_in_statements += ");\n";
- }
- } else {
- if (i > 0)
- c_args_var_content += ", ";
- if (arg_type->c_in.size())
- c_in_statements += sformat(arg_type->c_in, arg_type->c_type, c_param_name);
- c_args_var_content += sformat(arg_type->c_arg_in, c_param_name);
- }
+ for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
+ p_output.push_back(", ");
+ p_output.push_back(F->get().name);
+ }
- c_func_sig += ", ";
- c_func_sig += arg_type->c_type_in;
- c_func_sig += " ";
- c_func_sig += c_param_name;
+ p_output.push_back(");\n" CLOSE_BLOCK_L2);
- i++;
- }
+ return OK; // Won't increment method bind count
+ }
- const Map<const MethodInterface *, const InternalCall *>::Element *match = method_icalls_map.find(&E->get());
- ERR_FAIL_NULL_V(match, ERR_BUG);
+ const Map<const MethodInterface *, const InternalCall *>::Element *match = method_icalls_map.find(&p_imethod);
+ ERR_FAIL_NULL_V(match, ERR_BUG);
- const InternalCall *im_icall = match->value();
- String icall_method = im_icall->name;
+ const InternalCall *im_icall = match->value();
- if (!generated_icall_funcs.find(im_icall)) {
- generated_icall_funcs.push_back(im_icall);
+ String im_call = im_icall->editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS;
+ im_call += "." + im_icall->name + "(" + icall_params + ");\n";
- if (im_icall->editor_only)
- cpp_file.push_back("#ifdef TOOLS_ENABLED\n");
+ if (p_imethod.arguments.size())
+ p_output.push_back(cs_in_statements);
- // Generate icall function
+ if (return_type->name == "void") {
+ p_output.push_back(im_call);
+ } else if (return_type->cs_out.empty()) {
+ p_output.push_back("return " + im_call);
+ } else {
+ p_output.push_back(return_type->im_type_out);
+ p_output.push_back(" " LOCAL_RET " = ");
+ p_output.push_back(im_call);
+ p_output.push_back(INDENT3);
+ p_output.push_back(sformat(return_type->cs_out, LOCAL_RET) + "\n");
+ }
- cpp_file.push_back(ret_void ? "void " : return_type->c_type_out + " ");
- cpp_file.push_back(icall_method);
- cpp_file.push_back("(");
- cpp_file.push_back(c_func_sig);
- cpp_file.push_back(") " OPEN_BLOCK);
+ p_output.push_back(CLOSE_BLOCK_L2);
+ }
- String fail_ret = ret_void ? "" : ", " + (return_type->c_type_out.ends_with("*") ? "NULL" : return_type->c_type_out + "()");
+ p_method_bind_count++;
+ return OK;
+}
- if (!ret_void) {
- String ptrcall_return_type;
- String initialization;
+Error BindingsGenerator::generate_glue(const String &p_output_dir) {
- if (return_type->is_object_type) {
- ptrcall_return_type = return_type->is_reference ? "Ref<Reference>" : return_type->c_type;
- initialization = return_type->is_reference ? "" : " = NULL";
- } else {
- ptrcall_return_type = return_type->c_type;
- }
+ verbose_output = true;
- cpp_file.push_back("\t" + ptrcall_return_type);
- cpp_file.push_back(" " LOCAL_RET);
- cpp_file.push_back(initialization + ";\n");
- cpp_file.push_back("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE);
- cpp_file.push_back(fail_ret);
- cpp_file.push_back(");\n");
- } else {
- cpp_file.push_back("\tERR_FAIL_NULL(" CS_PARAM_INSTANCE ");\n");
- }
+ bool dir_exists = DirAccess::exists(p_output_dir);
+ ERR_EXPLAIN("The output directory does not exist.");
+ ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
- if (imethod.arguments.size()) {
- if (imethod.is_vararg) {
- String err_fail_macro = ret_void ? "ERR_FAIL_COND" : "ERR_FAIL_COND_V";
- String vararg_arg = "arg" + argc_str;
- String real_argc_str = itos(imethod.arguments.size() - 1); // Arguments count without vararg
-
- cpp_file.push_back("\tVector<Variant> varargs;\n"
- "\tint vararg_length = mono_array_length(");
- cpp_file.push_back(vararg_arg);
- cpp_file.push_back(");\n\tint total_length = ");
- cpp_file.push_back(real_argc_str);
- cpp_file.push_back(" + vararg_length;\n\t");
- cpp_file.push_back(err_fail_macro);
- cpp_file.push_back("(varargs.resize(vararg_length) != OK");
- cpp_file.push_back(fail_ret);
- cpp_file.push_back(");\n\tVector<Variant*> " C_LOCAL_PTRCALL_ARGS ";\n\t");
- cpp_file.push_back(err_fail_macro);
- cpp_file.push_back("(call_args.resize(total_length) != OK");
- cpp_file.push_back(fail_ret);
- cpp_file.push_back(");\n");
- cpp_file.push_back(c_in_statements);
- cpp_file.push_back("\tfor (int i = 0; i < vararg_length; i++) " OPEN_BLOCK
- "\t\tMonoObject* elem = mono_array_get(");
- cpp_file.push_back(vararg_arg);
- cpp_file.push_back(", MonoObject*, i);\n"
- "\t\tvarargs.set(i, GDMonoMarshal::mono_object_to_variant(elem));\n"
- "\t\t" C_LOCAL_PTRCALL_ARGS ".set(");
- cpp_file.push_back(real_argc_str);
- cpp_file.push_back(" + i, &varargs[i]);\n\t" CLOSE_BLOCK);
- } else {
- cpp_file.push_back(c_in_statements);
- cpp_file.push_back("\tconst void* " C_LOCAL_PTRCALL_ARGS "[");
- cpp_file.push_back(argc_str + "] = { ");
- cpp_file.push_back(c_args_var_content + " };\n");
- }
- }
+ List<String> output;
- if (imethod.is_vararg) {
- cpp_file.push_back("\tVariant::CallError vcall_error;\n\t");
+ output.push_back("#include \"" GLUE_HEADER_FILE "\"\n"
+ "\n");
- if (!ret_void)
- cpp_file.push_back(LOCAL_RET " = ");
+ generated_icall_funcs.clear();
- cpp_file.push_back(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", ");
- cpp_file.push_back(imethod.arguments.size() ? "(const Variant**)" C_LOCAL_PTRCALL_ARGS ".ptr()" : "NULL");
- cpp_file.push_back(", total_length, vcall_error);\n");
- } else {
- cpp_file.push_back("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", ");
- cpp_file.push_back(imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "NULL, ");
- cpp_file.push_back(!ret_void ? "&" LOCAL_RET ");\n" : "NULL);\n");
- }
+ for (Map<String, TypeInterface>::Element *type_elem = obj_types.front(); type_elem; type_elem = type_elem->next()) {
+ const TypeInterface &itype = type_elem->get();
- if (!ret_void) {
- if (return_type->c_out.empty())
- cpp_file.push_back("\treturn " LOCAL_RET ";\n");
- else
- cpp_file.push_back(sformat(return_type->c_out, return_type->c_type_out, LOCAL_RET, return_type->name));
- }
+ List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
+
+ OS::get_singleton()->print(String("Generating " + itype.name + "...\n").utf8());
- cpp_file.push_back(CLOSE_BLOCK "\n");
+ String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor");
- if (im_icall->editor_only)
- cpp_file.push_back("#endif // TOOLS_ENABLED\n");
+ for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
+ const MethodInterface &imethod = E->get();
+ Error method_err = _generate_glue_method(itype, imethod, output);
+ if (method_err != OK) {
+ ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
+ ERR_FAIL_V(method_err);
}
}
@@ -1324,11 +1167,11 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (!find_icall_by_name(singleton_icall.name, custom_icalls))
custom_icalls.push_back(singleton_icall);
- cpp_file.push_back("Object* ");
- cpp_file.push_back(singleton_icall_name);
- cpp_file.push_back("() " OPEN_BLOCK "\treturn ProjectSettings::get_singleton()->get_singleton_object(\"");
- cpp_file.push_back(itype.proxy_name);
- cpp_file.push_back("\");\n" CLOSE_BLOCK "\n");
+ output.push_back("Object* ");
+ output.push_back(singleton_icall_name);
+ output.push_back("() " OPEN_BLOCK "\treturn ProjectSettings::get_singleton()->get_singleton_object(\"");
+ output.push_back(itype.proxy_name);
+ output.push_back("\");\n" CLOSE_BLOCK "\n");
}
if (itype.is_instantiable) {
@@ -1337,36 +1180,36 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (!find_icall_by_name(ctor_icall.name, custom_icalls))
custom_icalls.push_back(ctor_icall);
- cpp_file.push_back("Object* ");
- cpp_file.push_back(ctor_method);
- cpp_file.push_back("(MonoObject* obj) " OPEN_BLOCK
- "\t" C_MACRO_OBJECT_CONSTRUCT "(instance, \"");
- cpp_file.push_back(itype.name);
- cpp_file.push_back("\");\n"
- "\t" C_METHOD_TIE_MANAGED_TO_UNMANAGED "(obj, instance);\n"
- "\treturn instance;\n" CLOSE_BLOCK "\n");
+ output.push_back("Object* ");
+ output.push_back(ctor_method);
+ output.push_back("(MonoObject* obj) " OPEN_BLOCK
+ "\t" C_MACRO_OBJECT_CONSTRUCT "(instance, \"");
+ output.push_back(itype.name);
+ output.push_back("\");\n"
+ "\t" C_METHOD_TIE_MANAGED_TO_UNMANAGED "(obj, instance);\n"
+ "\treturn instance;\n" CLOSE_BLOCK "\n");
}
}
- cpp_file.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK);
- cpp_file.push_back("uint64_t get_core_api_hash() { return ");
- cpp_file.push_back(itos(GDMono::get_singleton()->get_api_core_hash()) + "; }\n");
- cpp_file.push_back("#ifdef TOOLS_ENABLED\n"
- "uint64_t get_editor_api_hash() { return ");
- cpp_file.push_back(itos(GDMono::get_singleton()->get_api_editor_hash()) +
- "; }\n#endif // TOOLS_ENABLED\n");
- cpp_file.push_back("void register_generated_icalls() " OPEN_BLOCK);
-
-#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \
- { \
- cpp_file.push_back("\tmono_add_internal_call("); \
- cpp_file.push_back("\"" BINDINGS_NAMESPACE "."); \
- cpp_file.push_back(m_icall.editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS); \
- cpp_file.push_back("::"); \
- cpp_file.push_back(m_icall.name); \
- cpp_file.push_back("\", (void*)"); \
- cpp_file.push_back(m_icall.name); \
- cpp_file.push_back(");\n"); \
+ output.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK);
+ output.push_back("uint64_t get_core_api_hash() { return ");
+ output.push_back(itos(GDMono::get_singleton()->get_api_core_hash()) + "; }\n");
+ output.push_back("#ifdef TOOLS_ENABLED\n"
+ "uint64_t get_editor_api_hash() { return ");
+ output.push_back(itos(GDMono::get_singleton()->get_api_editor_hash()) +
+ "; }\n#endif // TOOLS_ENABLED\n");
+ output.push_back("void register_generated_icalls() " OPEN_BLOCK);
+
+#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \
+ { \
+ output.push_back("\tmono_add_internal_call("); \
+ output.push_back("\"" BINDINGS_NAMESPACE "."); \
+ output.push_back(m_icall.editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS); \
+ output.push_back("::"); \
+ output.push_back(m_icall.name); \
+ output.push_back("\", (void*)"); \
+ output.push_back(m_icall.name); \
+ output.push_back(");\n"); \
}
bool tools_sequence = false;
@@ -1375,11 +1218,11 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (tools_sequence) {
if (!E->get().editor_only) {
tools_sequence = false;
- cpp_file.push_back("#endif\n");
+ output.push_back("#endif\n");
}
} else {
if (E->get().editor_only) {
- cpp_file.push_back("#ifdef TOOLS_ENABLED\n");
+ output.push_back("#ifdef TOOLS_ENABLED\n");
tools_sequence = true;
}
}
@@ -1389,24 +1232,23 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (tools_sequence) {
tools_sequence = false;
- cpp_file.push_back("#endif\n");
+ output.push_back("#endif\n");
}
- cpp_file.push_back("#ifdef TOOLS_ENABLED\n");
+ output.push_back("#ifdef TOOLS_ENABLED\n");
for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next())
ADD_INTERNAL_CALL_REGISTRATION(E->get());
- cpp_file.push_back("#endif // TOOLS_ENABLED\n");
+ output.push_back("#endif // TOOLS_ENABLED\n");
for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) {
-
if (tools_sequence) {
if (!E->get().editor_only) {
tools_sequence = false;
- cpp_file.push_back("#endif\n");
+ output.push_back("#endif\n");
}
} else {
if (E->get().editor_only) {
- cpp_file.push_back("#ifdef TOOLS_ENABLED\n");
+ output.push_back("#ifdef TOOLS_ENABLED\n");
tools_sequence = true;
}
}
@@ -1416,20 +1258,27 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (tools_sequence) {
tools_sequence = false;
- cpp_file.push_back("#endif\n");
+ output.push_back("#endif\n");
}
#undef ADD_INTERNAL_CALL_REGISTRATION
- cpp_file.push_back(CLOSE_BLOCK "}\n");
+ output.push_back(CLOSE_BLOCK "}\n");
+
+ Error save_err = _save_file(path_join(p_output_dir, "mono_glue.gen.cpp"), output);
+ if (save_err != OK)
+ return save_err;
- return _save_file(path_join(p_output_dir, "mono_glue.gen.cpp"), cpp_file);
+ OS::get_singleton()->print("Mono glue generated successfully\n");
+
+ return OK;
}
Error BindingsGenerator::_save_file(const String &p_path, const List<String> &p_content) {
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
+ ERR_EXPLAIN("Cannot open file: " + p_path);
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
for (const List<String>::Element *E = p_content.front(); E; E = E->next()) {
@@ -1441,6 +1290,163 @@ Error BindingsGenerator::_save_file(const String &p_path, const List<String> &p_
return OK;
}
+Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, List<String> &p_output) {
+
+ if (p_imethod.is_virtual)
+ return OK; // Ignore
+
+ bool ret_void = p_imethod.return_type == "void";
+
+ const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
+
+ String argc_str = itos(p_imethod.arguments.size());
+
+ String c_func_sig = "MethodBind* " CS_PARAM_METHODBIND ", " + p_itype.c_type_in + " " CS_PARAM_INSTANCE;
+ String c_in_statements;
+ String c_args_var_content;
+
+ // Get arguments information
+ int i = 0;
+ for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
+ const ArgumentInterface &iarg = F->get();
+ const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
+
+ String c_param_name = "arg" + itos(i + 1);
+
+ if (p_imethod.is_vararg) {
+ if (i < p_imethod.arguments.size() - 1) {
+ c_in_statements += sformat(arg_type->c_in.size() ? arg_type->c_in : TypeInterface::DEFAULT_VARARG_C_IN, "Variant", c_param_name);
+ c_in_statements += "\t" C_LOCAL_PTRCALL_ARGS ".set(0, ";
+ c_in_statements += sformat("&%s_in", c_param_name);
+ c_in_statements += ");\n";
+ }
+ } else {
+ if (i > 0)
+ c_args_var_content += ", ";
+ if (arg_type->c_in.size())
+ c_in_statements += sformat(arg_type->c_in, arg_type->c_type, c_param_name);
+ c_args_var_content += sformat(arg_type->c_arg_in, c_param_name);
+ }
+
+ c_func_sig += ", ";
+ c_func_sig += arg_type->c_type_in;
+ c_func_sig += " ";
+ c_func_sig += c_param_name;
+
+ i++;
+ }
+
+ const Map<const MethodInterface *, const InternalCall *>::Element *match = method_icalls_map.find(&p_imethod);
+ ERR_FAIL_NULL_V(match, ERR_BUG);
+
+ const InternalCall *im_icall = match->value();
+ String icall_method = im_icall->name;
+
+ if (!generated_icall_funcs.find(im_icall)) {
+ generated_icall_funcs.push_back(im_icall);
+
+ if (im_icall->editor_only)
+ p_output.push_back("#ifdef TOOLS_ENABLED\n");
+
+ // Generate icall function
+
+ p_output.push_back(ret_void ? "void " : return_type->c_type_out + " ");
+ p_output.push_back(icall_method);
+ p_output.push_back("(");
+ p_output.push_back(c_func_sig);
+ p_output.push_back(") " OPEN_BLOCK);
+
+ String fail_ret = ret_void ? "" : ", " + (return_type->c_type_out.ends_with("*") ? "NULL" : return_type->c_type_out + "()");
+
+ if (!ret_void) {
+ String ptrcall_return_type;
+ String initialization;
+
+ if (return_type->is_object_type) {
+ ptrcall_return_type = return_type->is_reference ? "Ref<Reference>" : return_type->c_type;
+ initialization = return_type->is_reference ? "" : " = NULL";
+ } else {
+ ptrcall_return_type = return_type->c_type;
+ }
+
+ p_output.push_back("\t" + ptrcall_return_type);
+ p_output.push_back(" " LOCAL_RET);
+ p_output.push_back(initialization + ";\n");
+ p_output.push_back("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE);
+ p_output.push_back(fail_ret);
+ p_output.push_back(");\n");
+ } else {
+ p_output.push_back("\tERR_FAIL_NULL(" CS_PARAM_INSTANCE ");\n");
+ }
+
+ if (p_imethod.arguments.size()) {
+ if (p_imethod.is_vararg) {
+ String err_fail_macro = ret_void ? "ERR_FAIL_COND" : "ERR_FAIL_COND_V";
+ String vararg_arg = "arg" + argc_str;
+ String real_argc_str = itos(p_imethod.arguments.size() - 1); // Arguments count without vararg
+
+ p_output.push_back("\tVector<Variant> varargs;\n"
+ "\tint vararg_length = mono_array_length(");
+ p_output.push_back(vararg_arg);
+ p_output.push_back(");\n\tint total_length = ");
+ p_output.push_back(real_argc_str);
+ p_output.push_back(" + vararg_length;\n\t");
+ p_output.push_back(err_fail_macro);
+ p_output.push_back("(varargs.resize(vararg_length) != OK");
+ p_output.push_back(fail_ret);
+ p_output.push_back(");\n\tVector<Variant*> " C_LOCAL_PTRCALL_ARGS ";\n\t");
+ p_output.push_back(err_fail_macro);
+ p_output.push_back("(call_args.resize(total_length) != OK");
+ p_output.push_back(fail_ret);
+ p_output.push_back(");\n");
+ p_output.push_back(c_in_statements);
+ p_output.push_back("\tfor (int i = 0; i < vararg_length; i++) " OPEN_BLOCK
+ "\t\tMonoObject* elem = mono_array_get(");
+ p_output.push_back(vararg_arg);
+ p_output.push_back(", MonoObject*, i);\n"
+ "\t\tvarargs.set(i, GDMonoMarshal::mono_object_to_variant(elem));\n"
+ "\t\t" C_LOCAL_PTRCALL_ARGS ".set(");
+ p_output.push_back(real_argc_str);
+ p_output.push_back(" + i, &varargs[i]);\n\t" CLOSE_BLOCK);
+ } else {
+ p_output.push_back(c_in_statements);
+ p_output.push_back("\tconst void* " C_LOCAL_PTRCALL_ARGS "[");
+ p_output.push_back(argc_str + "] = { ");
+ p_output.push_back(c_args_var_content + " };\n");
+ }
+ }
+
+ if (p_imethod.is_vararg) {
+ p_output.push_back("\tVariant::CallError vcall_error;\n\t");
+
+ if (!ret_void)
+ p_output.push_back(LOCAL_RET " = ");
+
+ p_output.push_back(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", ");
+ p_output.push_back(p_imethod.arguments.size() ? "(const Variant**)" C_LOCAL_PTRCALL_ARGS ".ptr()" : "NULL");
+ p_output.push_back(", total_length, vcall_error);\n");
+ } else {
+ p_output.push_back("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", ");
+ p_output.push_back(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "NULL, ");
+ p_output.push_back(!ret_void ? "&" LOCAL_RET ");\n" : "NULL);\n");
+ }
+
+ if (!ret_void) {
+ if (return_type->c_out.empty())
+ p_output.push_back("\treturn " LOCAL_RET ";\n");
+ else
+ p_output.push_back(sformat(return_type->c_out, return_type->c_type_out, LOCAL_RET, return_type->name));
+ }
+
+ p_output.push_back(CLOSE_BLOCK "\n");
+
+ if (im_icall->editor_only)
+ p_output.push_back("#endif // TOOLS_ENABLED\n");
+ }
+
+ return OK;
+}
+
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_null(const String &p_name) {
const Map<String, TypeInterface>::Element *match = builtin_types.find(p_name);
@@ -1505,7 +1511,8 @@ void BindingsGenerator::_populate_object_type_interfaces() {
itype.memory_own = itype.is_reference;
if (!ClassDB::is_class_exposed(type_cname)) {
- WARN_PRINTS("Ignoring type " + String(type_cname) + " because it's not exposed");
+ if (verbose_output)
+ WARN_PRINTS("Ignoring type " + String(type_cname) + " because it's not exposed");
class_list.pop_front();
continue;
}
@@ -1569,9 +1576,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// which could actually will return something differnet.
// Let's put this to notify us if that ever happens.
if (itype.name != "Object" || imethod.name != "free") {
- WARN_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
- "We only expected Object.free, but found " +
- itype.name + "." + imethod.name);
+ if (verbose_output) {
+ WARN_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
+ "We only expected Object.free, but found " +
+ itype.name + "." + imethod.name);
+ }
}
} else {
ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
@@ -2077,7 +2086,8 @@ BindingsGenerator::BindingsGenerator() {
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
- int options_count = 3;
+ const int NUM_OPTIONS = 3;
+ int options_left = NUM_OPTIONS;
String mono_glue_option = "--generate-mono-glue";
String cs_core_api_option = "--generate-cs-core-api";
@@ -2087,33 +2097,35 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
const List<String>::Element *elem = p_cmdline_args.front();
- while (elem && options_count) {
+ while (elem && options_left) {
if (elem->get() == mono_glue_option) {
const List<String>::Element *path_elem = elem->next();
if (path_elem) {
- get_singleton().generate_glue(path_elem->get());
+ if (get_singleton().generate_glue(path_elem->get()) != OK)
+ ERR_PRINT("Mono glue generation failed");
elem = elem->next();
} else {
ERR_PRINTS("--generate-mono-glue: No output directory specified");
}
- --options_count;
+ --options_left;
} else if (elem->get() == cs_core_api_option) {
const List<String>::Element *path_elem = elem->next();
if (path_elem) {
- get_singleton().generate_cs_core_project(path_elem->get());
+ if (get_singleton().generate_cs_core_project(path_elem->get()) != OK)
+ ERR_PRINT("Generation of solution and C# project for the Core API failed");
elem = elem->next();
} else {
ERR_PRINTS(cs_core_api_option + ": No output directory specified");
}
- --options_count;
+ --options_left;
} else if (elem->get() == cs_editor_api_option) {
@@ -2121,7 +2133,8 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
if (path_elem) {
if (path_elem->next()) {
- get_singleton().generate_cs_editor_project(path_elem->get(), path_elem->next()->get());
+ if (get_singleton().generate_cs_editor_project(path_elem->get(), path_elem->next()->get()) != OK)
+ ERR_PRINT("Generation of solution and C# project for the Editor API failed");
elem = path_elem->next();
} else {
ERR_PRINTS(cs_editor_api_option + ": No hint path for the Core API dll specified");
@@ -2130,13 +2143,16 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
ERR_PRINTS(cs_editor_api_option + ": No output directory specified");
}
- --options_count;
+ --options_left;
}
elem = elem->next();
}
verbose_output = false;
+
+ if (options_left != NUM_OPTIONS)
+ exit(0);
}
#endif
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 437a566556..dfa3aa9911 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -368,6 +368,8 @@ class BindingsGenerator {
List<InternalCall> method_icalls;
Map<const MethodInterface *, const InternalCall *> method_icalls_map;
+ List<const InternalCall *> generated_icall_funcs;
+
List<InternalCall> core_custom_icalls;
List<InternalCall> editor_custom_icalls;
@@ -404,6 +406,11 @@ class BindingsGenerator {
Error _generate_cs_type(const TypeInterface &itype, const String &p_output_file);
+ Error _generate_cs_property(const TypeInterface &p_itype, const DocData::PropertyDoc &p_prop_doc, List<String> &p_output);
+ Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output);
+
+ Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, List<String> &p_output);
+
Error _save_file(const String &path, const List<String> &content);
BindingsGenerator();
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index 1bad8a3f85..b88d34fc33 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -32,6 +32,7 @@
#include "main/main.h"
#include "../godotsharp_dirs.h"
+#include "../mono_gd/gd_mono.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../utils/path_utils.h"
@@ -52,6 +53,10 @@ String _find_build_engine_on_unix(const String &p_name) {
if (ret.length())
return ret;
+ String ret_fallback = path_which(p_name + ".exe");
+ if (ret_fallback.length())
+ return ret_fallback;
+
const char *locations[] = {
#ifdef OSX_ENABLED
"/Library/Frameworks/Mono.framework/Versions/Current/bin/",
@@ -60,10 +65,10 @@ String _find_build_engine_on_unix(const String &p_name) {
};
for (int i = 0; i < sizeof(locations) / sizeof(const char *); i++) {
- String location = locations[i];
+ String hint_path = locations[i] + p_name;
- if (FileAccess::exists(location + p_name)) {
- return location;
+ if (FileAccess::exists(hint_path)) {
+ return hint_path;
}
}
@@ -71,7 +76,7 @@ String _find_build_engine_on_unix(const String &p_name) {
}
#endif
-MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
+void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, MonoString **r_framework_path) {
GodotSharpBuilds::BuildTool build_tool = GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool")));
@@ -84,11 +89,23 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
if (!msbuild_tools_path.ends_with("\\"))
msbuild_tools_path += "\\";
- return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe");
+ // FrameworkPathOverride
+ const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info();
+ if (mono_reg_info.assembly_dir.length()) {
+ *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe");
+
+ String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5");
+ *r_framework_path = GDMonoMarshal::mono_string_from_godot(framework_path);
+ } else {
+ ERR_PRINT("Cannot find Mono's assemblies directory in the registry");
+ }
+
+ return;
}
- OS::get_singleton()->print("Cannot find System's MSBuild. Trying with Mono's...\n");
- }
+ if (OS::get_singleton()->is_stdout_verbose())
+ OS::get_singleton()->print("Cannot find System's MSBuild. Trying with Mono's...\n");
+ } // fall through
case GodotSharpBuilds::MSBUILD_MONO: {
String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat");
@@ -96,17 +113,10 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
WARN_PRINTS("Cannot find msbuild ('mono/builds/build_tool'). Tried with path: " + msbuild_path);
}
- return GDMonoMarshal::mono_string_from_godot(msbuild_path);
- }
- case GodotSharpBuilds::XBUILD: {
- String xbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("xbuild.bat");
+ *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_path);
- if (!FileAccess::exists(xbuild_path)) {
- WARN_PRINTS("Cannot find xbuild ('mono/builds/build_tool'). Tried with path: " + xbuild_path);
- }
-
- return GDMonoMarshal::mono_string_from_godot(xbuild_path);
- }
+ return;
+ } break;
default:
ERR_EXPLAIN("You don't deserve to live");
CRASH_NOW();
@@ -118,25 +128,28 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
if (build_tool != GodotSharpBuilds::XBUILD) {
if (msbuild_path.empty()) {
WARN_PRINT("Cannot find msbuild ('mono/builds/build_tool').");
- return NULL;
+ return;
}
} else {
if (xbuild_path.empty()) {
WARN_PRINT("Cannot find xbuild ('mono/builds/build_tool').");
- return NULL;
+ return;
}
}
- return GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path);
+ *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path);
+
+ return;
#else
- return NULL;
+ ERR_PRINT("Not implemented on this platform");
+ return;
#endif
}
void GodotSharpBuilds::_register_internal_calls() {
mono_add_internal_call("GodotSharpTools.Build.BuildSystem::godot_icall_BuildInstance_ExitCallback", (void *)godot_icall_BuildInstance_ExitCallback);
- mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildPath", (void *)godot_icall_BuildInstance_get_MSBuildPath);
+ mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildInfo", (void *)godot_icall_BuildInstance_get_MSBuildInfo);
}
void GodotSharpBuilds::show_build_error_dialog(const String &p_message) {
@@ -269,7 +282,7 @@ bool GodotSharpBuilds::make_api_sln(GodotSharpBuilds::APIType p_api_type) {
return true;
}
-bool godotsharp_build_callback() {
+bool GodotSharpBuilds::build_project_blocking() {
if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path()))
return true; // No solution to build
@@ -348,14 +361,25 @@ GodotSharpBuilds::GodotSharpBuilds() {
singleton = this;
- EditorNode::get_singleton()->add_build_callback(&godotsharp_build_callback);
+ EditorNode::get_singleton()->add_build_callback(&GodotSharpBuilds::build_project_blocking);
// Build tool settings
EditorSettings *ed_settings = EditorSettings::get_singleton();
- if (!ed_settings->has_setting("mono/builds/build_tool")) {
- ed_settings->set_setting("mono/builds/build_tool", MSBUILD);
- }
- ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/builds/build_tool", PROPERTY_HINT_ENUM, "MSBuild (System),MSBuild (Mono),xbuild"));
+
+#ifdef WINDOWS_ENABLED
+ // TODO: Default to MSBUILD_MONO if its csc.exe issue is fixed in the installed mono version
+ EDITOR_DEF("mono/builds/build_tool", MSBUILD);
+#else
+ EDITOR_DEF("mono/builds/build_tool", MSBUILD_MONO);
+#endif
+
+ ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/builds/build_tool", PROPERTY_HINT_ENUM,
+#ifdef WINDOWS_ENABLED
+ "MSBuild (Mono),MSBuild (System)"
+#else
+ "MSBuild (Mono),xbuild (Deprecated)"
+#endif
+ ));
}
GodotSharpBuilds::~GodotSharpBuilds() {
@@ -395,10 +419,11 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) {
}
if (!exited) {
- ERR_PRINT("BuildProcess::start called, but process still running");
exited = true;
- build_tab->on_build_exec_failed("!exited");
- return;
+ String message = "Tried to start build process, but it is already running";
+ build_tab->on_build_exec_failed(message);
+ ERR_EXPLAIN(message);
+ ERR_FAIL();
}
exited = false;
@@ -410,10 +435,12 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) {
if (d->file_exists(issues_file)) {
Error err = d->remove(issues_file);
if (err != OK) {
- ERR_PRINTS("Cannot remove file: " + logs_dir.plus_file(issues_file));
exited = true;
- build_tab->on_build_exec_failed("Cannot remove file: " + issues_file);
- return;
+ String file_path = ProjectSettings::get_singleton()->localize_path(logs_dir).plus_file(issues_file);
+ String message = "Cannot remove issues file: " + file_path;
+ build_tab->on_build_exec_failed(message);
+ ERR_EXPLAIN(message);
+ ERR_FAIL();
}
}
@@ -434,7 +461,9 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) {
if (ex) {
exited = true;
- build_tab->on_build_exec_failed("The build constructor threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex));
+ String message = "The build constructor threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex);
+ build_tab->on_build_exec_failed(message);
+ ERR_EXPLAIN(message);
ERR_FAIL();
}
@@ -452,7 +481,9 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) {
if (ex) {
exited = true;
- build_tab->on_build_exec_failed("The build method threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex));
+ String message = "The build method threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex);
+ build_tab->on_build_exec_failed(message);
+ ERR_EXPLAIN(message);
ERR_FAIL();
}
diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h
index 6d5fa3b44a..7d2f38a774 100644
--- a/modules/mono/editor/godotsharp_builds.h
+++ b/modules/mono/editor/godotsharp_builds.h
@@ -67,9 +67,12 @@ public:
};
enum BuildTool {
- MSBUILD,
MSBUILD_MONO,
- XBUILD
+#ifdef WINDOWS_ENABLED
+ MSBUILD
+#else
+ XBUILD // Deprecated
+#endif
};
_FORCE_INLINE_ static GodotSharpBuilds *get_singleton() { return singleton; }
@@ -89,6 +92,8 @@ public:
static bool make_api_sln(APIType p_api_type);
+ static bool build_project_blocking();
+
GodotSharpBuilds();
~GodotSharpBuilds();
};
diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp
index 30e7653256..1bc1e8a515 100644
--- a/modules/mono/editor/godotsharp_editor.cpp
+++ b/modules/mono/editor/godotsharp_editor.cpp
@@ -46,21 +46,6 @@
#include "../utils/mono_reg_utils.h"
#endif
-class MonoReloadNode : public Node {
- GDCLASS(MonoReloadNode, Node)
-
-protected:
- void _notification(int p_what) {
- switch (p_what) {
- case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
- CSharpLanguage::get_singleton()->reload_assemblies_if_needed(true);
- } break;
- default: {
- } break;
- };
- }
-};
-
GodotSharpEditor *GodotSharpEditor::singleton = NULL;
bool GodotSharpEditor::_create_project_solution() {
@@ -71,6 +56,10 @@ bool GodotSharpEditor::_create_project_solution() {
String path = OS::get_singleton()->get_resource_dir();
String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
+
String guid = CSharpProject::generate_game_project(path, name);
if (guid.length()) {
@@ -182,11 +171,6 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int
String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
monodevel_instance->execute(script_path);
} break;
- case EDITOR_VISUAL_STUDIO:
- // TODO
- // devenv <PathToSolutionFolder>
- // devenv /edit <PathToCsFile> /command "edit.goto <Line>"
- // HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7
default:
return ERR_UNAVAILABLE;
}
@@ -237,10 +221,8 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) {
// External editor settings
EditorSettings *ed_settings = EditorSettings::get_singleton();
- if (!ed_settings->has_setting("mono/editor/external_editor")) {
- ed_settings->set_setting("mono/editor/external_editor", EDITOR_NONE);
- }
- ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/editor/external_editor", PROPERTY_HINT_ENUM, "None,MonoDevelop,Visual Studio,Visual Studio Code"));
+ EDITOR_DEF("mono/editor/external_editor", EDITOR_NONE);
+ ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/editor/external_editor", PROPERTY_HINT_ENUM, "None,MonoDevelop,Visual Studio Code"));
}
GodotSharpEditor::~GodotSharpEditor() {
@@ -254,3 +236,49 @@ GodotSharpEditor::~GodotSharpEditor() {
monodevel_instance = NULL;
}
}
+
+MonoReloadNode *MonoReloadNode::singleton = NULL;
+
+void MonoReloadNode::_reload_timer_timeout() {
+
+ CSharpLanguage::get_singleton()->reload_assemblies_if_needed(false);
+}
+
+void MonoReloadNode::restart_reload_timer() {
+
+ reload_timer->stop();
+ reload_timer->start();
+}
+
+void MonoReloadNode::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_reload_timer_timeout"), &MonoReloadNode::_reload_timer_timeout);
+}
+
+void MonoReloadNode::_notification(int p_what) {
+ switch (p_what) {
+ case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+ restart_reload_timer();
+ CSharpLanguage::get_singleton()->reload_assemblies_if_needed(true);
+ } break;
+ default: {
+ } break;
+ };
+}
+
+MonoReloadNode::MonoReloadNode() {
+
+ singleton = this;
+
+ reload_timer = memnew(Timer);
+ add_child(reload_timer);
+ reload_timer->set_one_shot(false);
+ reload_timer->set_wait_time(EDITOR_DEF("mono/assembly_watch_interval_sec", 0.5));
+ reload_timer->connect("timeout", this, "_reload_timer_timeout");
+ reload_timer->start();
+}
+
+MonoReloadNode::~MonoReloadNode() {
+
+ singleton = NULL;
+}
diff --git a/modules/mono/editor/godotsharp_editor.h b/modules/mono/editor/godotsharp_editor.h
index 1ecb8c7a94..0f2c163582 100644
--- a/modules/mono/editor/godotsharp_editor.h
+++ b/modules/mono/editor/godotsharp_editor.h
@@ -69,7 +69,6 @@ public:
enum ExternalEditor {
EDITOR_NONE,
EDITOR_MONODEVELOP,
- EDITOR_VISUAL_STUDIO,
EDITOR_CODE,
};
@@ -84,4 +83,27 @@ public:
~GodotSharpEditor();
};
+class MonoReloadNode : public Node {
+ GDCLASS(MonoReloadNode, Node)
+
+ Timer *reload_timer;
+
+ void _reload_timer_timeout();
+
+ static MonoReloadNode *singleton;
+
+protected:
+ static void _bind_methods();
+
+ void _notification(int p_what);
+
+public:
+ _FORCE_INLINE_ static MonoReloadNode *get_singleton() { return singleton; }
+
+ void restart_reload_timer();
+
+ MonoReloadNode();
+ ~MonoReloadNode();
+};
+
#endif // GODOTSHARP_EDITOR_H
diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp
index 07109eaac7..31dc09856a 100644
--- a/modules/mono/editor/mono_bottom_panel.cpp
+++ b/modules/mono/editor/mono_bottom_panel.cpp
@@ -139,6 +139,14 @@ void MonoBottomPanel::_errors_toggled(bool p_pressed) {
build_tab->_update_issues_list();
}
+void MonoBottomPanel::_build_project_pressed() {
+
+ GodotSharpBuilds::get_singleton()->build_project_blocking();
+
+ MonoReloadNode::get_singleton()->restart_reload_timer();
+ CSharpLanguage::get_singleton()->reload_assemblies_if_needed(true);
+}
+
void MonoBottomPanel::_notification(int p_what) {
switch (p_what) {
@@ -153,6 +161,7 @@ void MonoBottomPanel::_notification(int p_what) {
void MonoBottomPanel::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_build_project_pressed"), &MonoBottomPanel::_build_project_pressed);
ClassDB::bind_method(D_METHOD("_warnings_toggled", "pressed"), &MonoBottomPanel::_warnings_toggled);
ClassDB::bind_method(D_METHOD("_errors_toggled", "pressed"), &MonoBottomPanel::_errors_toggled);
ClassDB::bind_method(D_METHOD("_build_tab_item_selected", "idx"), &MonoBottomPanel::_build_tab_item_selected);
@@ -187,6 +196,12 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) {
toolbar_hbc->set_h_size_flags(SIZE_EXPAND_FILL);
panel_builds_tab->add_child(toolbar_hbc);
+ ToolButton *build_project_btn = memnew(ToolButton);
+ build_project_btn->set_text("Build Project");
+ build_project_btn->set_focus_mode(FOCUS_NONE);
+ build_project_btn->connect("pressed", this, "_build_project_pressed");
+ toolbar_hbc->add_child(build_project_btn);
+
toolbar_hbc->add_spacer();
warnings_btn = memnew(ToolButton);
@@ -280,7 +295,11 @@ void MonoBuildTab::_update_issues_list() {
String tooltip;
tooltip += String("Message: ") + issue.message;
- tooltip += String("\nCode: ") + issue.code;
+
+ if (issue.code.length()) {
+ tooltip += String("\nCode: ") + issue.code;
+ }
+
tooltip += String("\nType: ") + (issue.warning ? "warning" : "error");
String text;
@@ -356,23 +375,21 @@ void MonoBuildTab::on_build_exit(BuildResult result) {
MonoBottomPanel::get_singleton()->raise_build_tab(this);
}
-void MonoBuildTab::on_build_exec_failed(const String &p_cause, const String &p_detailed) {
+void MonoBuildTab::on_build_exec_failed(const String &p_cause) {
build_exited = true;
build_result = RESULT_ERROR;
issues_list->clear();
- String tooltip;
+ BuildIssue issue;
+ issue.message = p_cause;
+ issue.warning = false;
- tooltip += "Message: " + (p_detailed.length() ? p_detailed : p_cause);
- tooltip += "\nType: error";
+ error_count += 1;
+ issues.push_back(issue);
- int line_break_idx = p_cause.find("\n");
- issues_list->add_item(line_break_idx == -1 ? p_cause : p_cause.substr(0, line_break_idx),
- get_icon("Error", "EditorIcons"));
- int index = issues_list->get_item_count() - 1;
- issues_list->set_item_tooltip(index, tooltip);
+ _update_issues_list();
MonoBottomPanel::get_singleton()->raise_build_tab(this);
}
diff --git a/modules/mono/editor/mono_bottom_panel.h b/modules/mono/editor/mono_bottom_panel.h
index 909fa4b385..5cc4aa3240 100644
--- a/modules/mono/editor/mono_bottom_panel.h
+++ b/modules/mono/editor/mono_bottom_panel.h
@@ -61,6 +61,8 @@ class MonoBottomPanel : public VBoxContainer {
void _warnings_toggled(bool p_pressed);
void _errors_toggled(bool p_pressed);
+ void _build_project_pressed();
+
static MonoBottomPanel *singleton;
protected:
@@ -134,7 +136,7 @@ public:
void on_build_start();
void on_build_exit(BuildResult result);
- void on_build_exec_failed(const String &p_cause, const String &p_detailed = String());
+ void on_build_exec_failed(const String &p_cause);
void restart_build();
void stop_build();
diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs
index df88a46832..0a00f83d47 100644
--- a/modules/mono/glue/cs_files/Color.cs
+++ b/modules/mono/glue/cs_files/Color.cs
@@ -1,590 +1,590 @@
-using System;
-
-namespace Godot
-{
- public struct Color : IEquatable<Color>
- {
- public float r;
- public float g;
- public float b;
- public float a;
-
- public int r8
- {
- get
- {
- return (int)(r * 255.0f);
- }
- }
-
- public int g8
- {
- get
- {
- return (int)(g * 255.0f);
- }
- }
-
- public int b8
- {
- get
- {
- return (int)(b * 255.0f);
- }
- }
-
- public int a8
- {
- get
- {
- return (int)(a * 255.0f);
- }
- }
-
- public float h
- {
- get
- {
- float max = Mathf.max(r, Mathf.max(g, b));
- float min = Mathf.min(r, Mathf.min(g, b));
-
- float delta = max - min;
-
- if (delta == 0)
- return 0;
-
- float h;
-
- if (r == max)
- h = (g - b) / delta; // Between yellow & magenta
- else if (g == max)
- h = 2 + (b - r) / delta; // Between cyan & yellow
- else
- h = 4 + (r - g) / delta; // Between magenta & cyan
-
- h /= 6.0f;
-
- if (h < 0)
- h += 1.0f;
-
- return h;
- }
- set
- {
- this = from_hsv(value, s, v);
- }
- }
-
- public float s
- {
- get
- {
- float max = Mathf.max(r, Mathf.max(g, b));
- float min = Mathf.min(r, Mathf.min(g, b));
-
- float delta = max - min;
-
- return max != 0 ? delta / max : 0;
- }
- set
- {
- this = from_hsv(h, value, v);
- }
- }
-
- public float v
- {
- get
- {
- return Mathf.max(r, Mathf.max(g, b));
- }
- set
- {
- this = from_hsv(h, s, value);
- }
- }
-
- private static readonly Color black = new Color(0f, 0f, 0f, 1.0f);
-
- public Color Black
- {
- get
- {
- return black;
- }
- }
-
- public float this [int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return r;
- case 1:
- return g;
- case 2:
- return b;
- case 3:
- return a;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- set
- {
- switch (index)
- {
- case 0:
- r = value;
- return;
- case 1:
- g = value;
- return;
- case 2:
- b = value;
- return;
- case 3:
- a = value;
- return;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
-
- public static void to_hsv(Color color, out float hue, out float saturation, out float value)
- {
- int max = Mathf.max(color.r8, Mathf.max(color.g8, color.b8));
- int min = Mathf.min(color.r8, Mathf.min(color.g8, color.b8));
-
- float delta = max - min;
-
- if (delta == 0)
- {
- hue = 0;
- }
- else
- {
- if (color.r == max)
- hue = (color.g - color.b) / delta; // Between yellow & magenta
- else if (color.g == max)
- hue = 2 + (color.b - color.r) / delta; // Between cyan & yellow
- else
- hue = 4 + (color.r - color.g) / delta; // Between magenta & cyan
-
- hue /= 6.0f;
-
- if (hue < 0)
- hue += 1.0f;
- }
-
- saturation = (max == 0) ? 0 : 1f - (1f * min / max);
- value = max / 255f;
- }
-
- public static Color from_hsv(float hue, float saturation, float value, float alpha = 1.0f)
- {
- if (saturation == 0)
- {
- // acp_hromatic (grey)
- return new Color(value, value, value, alpha);
- }
-
- int i;
- float f, p, q, t;
-
- hue *= 6.0f;
- hue %= 6f;
- i = (int)hue;
-
- f = hue - i;
- p = value * (1 - saturation);
- q = value * (1 - saturation * f);
- t = value * (1 - saturation * (1 - f));
-
- switch (i)
- {
- case 0: // Red is the dominant color
- return new Color(value, t, p, alpha);
- case 1: // Green is the dominant color
- return new Color(q, value, p, alpha);
- case 2:
- return new Color(p, value, t, alpha);
- case 3: // Blue is the dominant color
- return new Color(p, q, value, alpha);
- case 4:
- return new Color(t, p, value, alpha);
- default: // (5) Red is the dominant color
- return new Color(value, p, q, alpha);
- }
- }
-
- public Color blend(Color over)
- {
- Color res;
-
- float sa = 1.0f - over.a;
- res.a = a * sa + over.a;
-
- if (res.a == 0)
- {
- return new Color(0, 0, 0, 0);
- }
- else
- {
- res.r = (r * a * sa + over.r * over.a) / res.a;
- res.g = (g * a * sa + over.g * over.a) / res.a;
- res.b = (b * a * sa + over.b * over.a) / res.a;
- }
-
- return res;
- }
-
- public Color contrasted()
- {
- return new Color(
- (r + 0.5f) % 1.0f,
- (g + 0.5f) % 1.0f,
- (b + 0.5f) % 1.0f
- );
- }
-
- public float gray()
- {
- return (r + g + b) / 3.0f;
- }
-
- public Color inverted()
- {
- return new Color(
- 1.0f - r,
- 1.0f - g,
- 1.0f - b
- );
- }
-
- public Color linear_interpolate(Color b, float t)
- {
- Color res = this;
-
- res.r += (t * (b.r - this.r));
- res.g += (t * (b.g - this.g));
- res.b += (t * (b.b - this.b));
- res.a += (t * (b.a - this.a));
-
- return res;
- }
-
- public int to_32()
- {
- int c = (byte)(a * 255);
- c <<= 8;
- c |= (byte)(r * 255);
- c <<= 8;
- c |= (byte)(g * 255);
- c <<= 8;
- c |= (byte)(b * 255);
-
- return c;
- }
-
- public int to_ARGB32()
- {
- int c = (byte)(a * 255);
- c <<= 8;
- c |= (byte)(r * 255);
- c <<= 8;
- c |= (byte)(g * 255);
- c <<= 8;
- c |= (byte)(b * 255);
-
- return c;
- }
-
- public string to_html(bool include_alpha = true)
- {
- String txt = string.Empty;
-
- txt += _to_hex(r);
- txt += _to_hex(g);
- txt += _to_hex(b);
-
- if (include_alpha)
- txt = _to_hex(a) + txt;
-
- return txt;
- }
-
- public Color(float r, float g, float b, float a = 1.0f)
- {
- this.r = r;
- this.g = g;
- this.b = b;
- this.a = a;
- }
-
- public Color(int rgba)
- {
- this.a = (rgba & 0xFF) / 255.0f;
- rgba >>= 8;
- this.b = (rgba & 0xFF) / 255.0f;
- rgba >>= 8;
- this.g = (rgba & 0xFF) / 255.0f;
- rgba >>= 8;
- this.r = (rgba & 0xFF) / 255.0f;
- }
-
- private static float _parse_col(string str, int ofs)
- {
- int ig = 0;
-
- for (int i = 0; i < 2; i++)
- {
- int c = str[i + ofs];
- int v = 0;
-
- if (c >= '0' && c <= '9')
- {
- v = c - '0';
- }
- else if (c >= 'a' && c <= 'f')
- {
- v = c - 'a';
- v += 10;
- }
- else if (c >= 'A' && c <= 'F')
- {
- v = c - 'A';
- v += 10;
- }
- else
- {
- return -1;
- }
-
- if (i == 0)
- ig += v * 16;
- else
- ig += v;
- }
-
- return ig;
- }
-
- private String _to_hex(float val)
- {
- int v = (int)Mathf.clamp(val * 255.0f, 0, 255);
-
- string ret = string.Empty;
-
- for (int i = 0; i < 2; i++)
- {
- char[] c = { (char)0, (char)0 };
- int lv = v & 0xF;
-
- if (lv < 10)
- c[0] = (char)('0' + lv);
- else
- c[0] = (char)('a' + lv - 10);
-
- v >>= 4;
- ret = c + ret;
- }
-
- return ret;
- }
-
- internal static bool html_is_valid(string color)
- {
- if (color.Length == 0)
- return false;
-
- if (color[0] == '#')
- color = color.Substring(1, color.Length - 1);
-
- bool alpha = false;
-
- if (color.Length == 8)
- alpha = true;
- else if (color.Length == 6)
- alpha = false;
- else
- return false;
-
- if (alpha)
- {
- if ((int)_parse_col(color, 0) < 0)
- return false;
- }
-
- int from = alpha ? 2 : 0;
-
- if ((int)_parse_col(color, from + 0) < 0)
- return false;
- if ((int)_parse_col(color, from + 2) < 0)
- return false;
- if ((int)_parse_col(color, from + 4) < 0)
- return false;
-
- return true;
- }
-
- public static Color Color8(byte r8, byte g8, byte b8, byte a8)
- {
- return new Color((float)r8 / 255f, (float)g8 / 255f, (float)b8 / 255f, (float)a8 / 255f);
- }
-
- public Color(string rgba)
- {
- if (rgba.Length == 0)
- {
- r = 0f;
- g = 0f;
- b = 0f;
- a = 1.0f;
- return;
- }
-
- if (rgba[0] == '#')
- rgba = rgba.Substring(1);
-
- bool alpha = false;
-
- if (rgba.Length == 8)
- {
- alpha = true;
- }
- else if (rgba.Length == 6)
- {
- alpha = false;
- }
- else
- {
- throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
- }
-
- if (alpha)
- {
- a = _parse_col(rgba, 0);
-
- if (a < 0)
- throw new ArgumentOutOfRangeException("Invalid color code. Alpha is " + a + " but zero or greater is expected: " + rgba);
- }
- else
- {
- a = 1.0f;
- }
-
- int from = alpha ? 2 : 0;
-
- r = _parse_col(rgba, from + 0);
-
- if (r < 0)
- throw new ArgumentOutOfRangeException("Invalid color code. Red is " + r + " but zero or greater is expected: " + rgba);
-
- g = _parse_col(rgba, from + 2);
-
- if (g < 0)
- throw new ArgumentOutOfRangeException("Invalid color code. Green is " + g + " but zero or greater is expected: " + rgba);
-
- b = _parse_col(rgba, from + 4);
-
- if (b < 0)
- throw new ArgumentOutOfRangeException("Invalid color code. Blue is " + b + " but zero or greater is expected: " + rgba);
- }
-
- public static bool operator ==(Color left, Color right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(Color left, Color right)
- {
- return !left.Equals(right);
- }
-
- public static bool operator <(Color left, Color right)
- {
- if (left.r == right.r)
- {
- if (left.g == right.g)
- {
- if (left.b == right.b)
- return (left.a < right.a);
- else
- return (left.b < right.b);
- }
- else
- {
- return left.g < right.g;
- }
- }
-
- return left.r < right.r;
- }
-
- public static bool operator >(Color left, Color right)
- {
- if (left.r == right.r)
- {
- if (left.g == right.g)
- {
- if (left.b == right.b)
- return (left.a > right.a);
- else
- return (left.b > right.b);
- }
- else
- {
- return left.g > right.g;
- }
- }
-
- return left.r > right.r;
- }
-
- public override bool Equals(object obj)
- {
- if (obj is Color)
- {
- return Equals((Color)obj);
- }
-
- return false;
- }
-
- public bool Equals(Color other)
- {
- return r == other.r && g == other.g && b == other.b && a == other.a;
- }
-
- public override int GetHashCode()
- {
- return r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode() ^ a.GetHashCode();
- }
-
- public override string ToString()
- {
- return String.Format("{0},{1},{2},{3}", new object[]
- {
- this.r.ToString(),
- this.g.ToString(),
- this.b.ToString(),
- this.a.ToString()
- });
- }
-
- public string ToString(string format)
- {
- return String.Format("{0},{1},{2},{3}", new object[]
- {
- this.r.ToString(format),
- this.g.ToString(format),
- this.b.ToString(format),
- this.a.ToString(format)
- });
- }
- }
-}
+using System;
+
+namespace Godot
+{
+ public struct Color : IEquatable<Color>
+ {
+ public float r;
+ public float g;
+ public float b;
+ public float a;
+
+ public int r8
+ {
+ get
+ {
+ return (int)(r * 255.0f);
+ }
+ }
+
+ public int g8
+ {
+ get
+ {
+ return (int)(g * 255.0f);
+ }
+ }
+
+ public int b8
+ {
+ get
+ {
+ return (int)(b * 255.0f);
+ }
+ }
+
+ public int a8
+ {
+ get
+ {
+ return (int)(a * 255.0f);
+ }
+ }
+
+ public float h
+ {
+ get
+ {
+ float max = Mathf.max(r, Mathf.max(g, b));
+ float min = Mathf.min(r, Mathf.min(g, b));
+
+ float delta = max - min;
+
+ if (delta == 0)
+ return 0;
+
+ float h;
+
+ if (r == max)
+ h = (g - b) / delta; // Between yellow & magenta
+ else if (g == max)
+ h = 2 + (b - r) / delta; // Between cyan & yellow
+ else
+ h = 4 + (r - g) / delta; // Between magenta & cyan
+
+ h /= 6.0f;
+
+ if (h < 0)
+ h += 1.0f;
+
+ return h;
+ }
+ set
+ {
+ this = from_hsv(value, s, v);
+ }
+ }
+
+ public float s
+ {
+ get
+ {
+ float max = Mathf.max(r, Mathf.max(g, b));
+ float min = Mathf.min(r, Mathf.min(g, b));
+
+ float delta = max - min;
+
+ return max != 0 ? delta / max : 0;
+ }
+ set
+ {
+ this = from_hsv(h, value, v);
+ }
+ }
+
+ public float v
+ {
+ get
+ {
+ return Mathf.max(r, Mathf.max(g, b));
+ }
+ set
+ {
+ this = from_hsv(h, s, value);
+ }
+ }
+
+ private static readonly Color black = new Color(0f, 0f, 0f, 1.0f);
+
+ public Color Black
+ {
+ get
+ {
+ return black;
+ }
+ }
+
+ public float this [int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return r;
+ case 1:
+ return g;
+ case 2:
+ return b;
+ case 3:
+ return a;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ switch (index)
+ {
+ case 0:
+ r = value;
+ return;
+ case 1:
+ g = value;
+ return;
+ case 2:
+ b = value;
+ return;
+ case 3:
+ a = value;
+ return;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+
+ public static void to_hsv(Color color, out float hue, out float saturation, out float value)
+ {
+ int max = Mathf.max(color.r8, Mathf.max(color.g8, color.b8));
+ int min = Mathf.min(color.r8, Mathf.min(color.g8, color.b8));
+
+ float delta = max - min;
+
+ if (delta == 0)
+ {
+ hue = 0;
+ }
+ else
+ {
+ if (color.r == max)
+ hue = (color.g - color.b) / delta; // Between yellow & magenta
+ else if (color.g == max)
+ hue = 2 + (color.b - color.r) / delta; // Between cyan & yellow
+ else
+ hue = 4 + (color.r - color.g) / delta; // Between magenta & cyan
+
+ hue /= 6.0f;
+
+ if (hue < 0)
+ hue += 1.0f;
+ }
+
+ saturation = (max == 0) ? 0 : 1f - (1f * min / max);
+ value = max / 255f;
+ }
+
+ public static Color from_hsv(float hue, float saturation, float value, float alpha = 1.0f)
+ {
+ if (saturation == 0)
+ {
+ // acp_hromatic (grey)
+ return new Color(value, value, value, alpha);
+ }
+
+ int i;
+ float f, p, q, t;
+
+ hue *= 6.0f;
+ hue %= 6f;
+ i = (int)hue;
+
+ f = hue - i;
+ p = value * (1 - saturation);
+ q = value * (1 - saturation * f);
+ t = value * (1 - saturation * (1 - f));
+
+ switch (i)
+ {
+ case 0: // Red is the dominant color
+ return new Color(value, t, p, alpha);
+ case 1: // Green is the dominant color
+ return new Color(q, value, p, alpha);
+ case 2:
+ return new Color(p, value, t, alpha);
+ case 3: // Blue is the dominant color
+ return new Color(p, q, value, alpha);
+ case 4:
+ return new Color(t, p, value, alpha);
+ default: // (5) Red is the dominant color
+ return new Color(value, p, q, alpha);
+ }
+ }
+
+ public Color blend(Color over)
+ {
+ Color res;
+
+ float sa = 1.0f - over.a;
+ res.a = a * sa + over.a;
+
+ if (res.a == 0)
+ {
+ return new Color(0, 0, 0, 0);
+ }
+ else
+ {
+ res.r = (r * a * sa + over.r * over.a) / res.a;
+ res.g = (g * a * sa + over.g * over.a) / res.a;
+ res.b = (b * a * sa + over.b * over.a) / res.a;
+ }
+
+ return res;
+ }
+
+ public Color contrasted()
+ {
+ return new Color(
+ (r + 0.5f) % 1.0f,
+ (g + 0.5f) % 1.0f,
+ (b + 0.5f) % 1.0f
+ );
+ }
+
+ public float gray()
+ {
+ return (r + g + b) / 3.0f;
+ }
+
+ public Color inverted()
+ {
+ return new Color(
+ 1.0f - r,
+ 1.0f - g,
+ 1.0f - b
+ );
+ }
+
+ public Color linear_interpolate(Color b, float t)
+ {
+ Color res = this;
+
+ res.r += (t * (b.r - this.r));
+ res.g += (t * (b.g - this.g));
+ res.b += (t * (b.b - this.b));
+ res.a += (t * (b.a - this.a));
+
+ return res;
+ }
+
+ public int to_32()
+ {
+ int c = (byte)(a * 255);
+ c <<= 8;
+ c |= (byte)(r * 255);
+ c <<= 8;
+ c |= (byte)(g * 255);
+ c <<= 8;
+ c |= (byte)(b * 255);
+
+ return c;
+ }
+
+ public int to_ARGB32()
+ {
+ int c = (byte)(a * 255);
+ c <<= 8;
+ c |= (byte)(r * 255);
+ c <<= 8;
+ c |= (byte)(g * 255);
+ c <<= 8;
+ c |= (byte)(b * 255);
+
+ return c;
+ }
+
+ public string to_html(bool include_alpha = true)
+ {
+ String txt = string.Empty;
+
+ txt += _to_hex(r);
+ txt += _to_hex(g);
+ txt += _to_hex(b);
+
+ if (include_alpha)
+ txt = _to_hex(a) + txt;
+
+ return txt;
+ }
+
+ public Color(float r, float g, float b, float a = 1.0f)
+ {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ }
+
+ public Color(int rgba)
+ {
+ this.a = (rgba & 0xFF) / 255.0f;
+ rgba >>= 8;
+ this.b = (rgba & 0xFF) / 255.0f;
+ rgba >>= 8;
+ this.g = (rgba & 0xFF) / 255.0f;
+ rgba >>= 8;
+ this.r = (rgba & 0xFF) / 255.0f;
+ }
+
+ private static float _parse_col(string str, int ofs)
+ {
+ int ig = 0;
+
+ for (int i = 0; i < 2; i++)
+ {
+ int c = str[i + ofs];
+ int v = 0;
+
+ if (c >= '0' && c <= '9')
+ {
+ v = c - '0';
+ }
+ else if (c >= 'a' && c <= 'f')
+ {
+ v = c - 'a';
+ v += 10;
+ }
+ else if (c >= 'A' && c <= 'F')
+ {
+ v = c - 'A';
+ v += 10;
+ }
+ else
+ {
+ return -1;
+ }
+
+ if (i == 0)
+ ig += v * 16;
+ else
+ ig += v;
+ }
+
+ return ig;
+ }
+
+ private String _to_hex(float val)
+ {
+ int v = (int)Mathf.clamp(val * 255.0f, 0, 255);
+
+ string ret = string.Empty;
+
+ for (int i = 0; i < 2; i++)
+ {
+ char[] c = { (char)0, (char)0 };
+ int lv = v & 0xF;
+
+ if (lv < 10)
+ c[0] = (char)('0' + lv);
+ else
+ c[0] = (char)('a' + lv - 10);
+
+ v >>= 4;
+ ret = c + ret;
+ }
+
+ return ret;
+ }
+
+ internal static bool html_is_valid(string color)
+ {
+ if (color.Length == 0)
+ return false;
+
+ if (color[0] == '#')
+ color = color.Substring(1, color.Length - 1);
+
+ bool alpha = false;
+
+ if (color.Length == 8)
+ alpha = true;
+ else if (color.Length == 6)
+ alpha = false;
+ else
+ return false;
+
+ if (alpha)
+ {
+ if ((int)_parse_col(color, 0) < 0)
+ return false;
+ }
+
+ int from = alpha ? 2 : 0;
+
+ if ((int)_parse_col(color, from + 0) < 0)
+ return false;
+ if ((int)_parse_col(color, from + 2) < 0)
+ return false;
+ if ((int)_parse_col(color, from + 4) < 0)
+ return false;
+
+ return true;
+ }
+
+ public static Color Color8(byte r8, byte g8, byte b8, byte a8)
+ {
+ return new Color((float)r8 / 255f, (float)g8 / 255f, (float)b8 / 255f, (float)a8 / 255f);
+ }
+
+ public Color(string rgba)
+ {
+ if (rgba.Length == 0)
+ {
+ r = 0f;
+ g = 0f;
+ b = 0f;
+ a = 1.0f;
+ return;
+ }
+
+ if (rgba[0] == '#')
+ rgba = rgba.Substring(1);
+
+ bool alpha = false;
+
+ if (rgba.Length == 8)
+ {
+ alpha = true;
+ }
+ else if (rgba.Length == 6)
+ {
+ alpha = false;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
+ }
+
+ if (alpha)
+ {
+ a = _parse_col(rgba, 0);
+
+ if (a < 0)
+ throw new ArgumentOutOfRangeException("Invalid color code. Alpha is " + a + " but zero or greater is expected: " + rgba);
+ }
+ else
+ {
+ a = 1.0f;
+ }
+
+ int from = alpha ? 2 : 0;
+
+ r = _parse_col(rgba, from + 0);
+
+ if (r < 0)
+ throw new ArgumentOutOfRangeException("Invalid color code. Red is " + r + " but zero or greater is expected: " + rgba);
+
+ g = _parse_col(rgba, from + 2);
+
+ if (g < 0)
+ throw new ArgumentOutOfRangeException("Invalid color code. Green is " + g + " but zero or greater is expected: " + rgba);
+
+ b = _parse_col(rgba, from + 4);
+
+ if (b < 0)
+ throw new ArgumentOutOfRangeException("Invalid color code. Blue is " + b + " but zero or greater is expected: " + rgba);
+ }
+
+ public static bool operator ==(Color left, Color right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Color left, Color right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator <(Color left, Color right)
+ {
+ if (left.r == right.r)
+ {
+ if (left.g == right.g)
+ {
+ if (left.b == right.b)
+ return (left.a < right.a);
+ else
+ return (left.b < right.b);
+ }
+ else
+ {
+ return left.g < right.g;
+ }
+ }
+
+ return left.r < right.r;
+ }
+
+ public static bool operator >(Color left, Color right)
+ {
+ if (left.r == right.r)
+ {
+ if (left.g == right.g)
+ {
+ if (left.b == right.b)
+ return (left.a > right.a);
+ else
+ return (left.b > right.b);
+ }
+ else
+ {
+ return left.g > right.g;
+ }
+ }
+
+ return left.r > right.r;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Color)
+ {
+ return Equals((Color)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Color other)
+ {
+ return r == other.r && g == other.g && b == other.b && a == other.a;
+ }
+
+ public override int GetHashCode()
+ {
+ return r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode() ^ a.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0},{1},{2},{3}", new object[]
+ {
+ this.r.ToString(),
+ this.g.ToString(),
+ this.b.ToString(),
+ this.a.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("{0},{1},{2},{3}", new object[]
+ {
+ this.r.ToString(format),
+ this.g.ToString(format),
+ this.b.ToString(format),
+ this.a.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/ExportAttribute.cs b/modules/mono/glue/cs_files/ExportAttribute.cs
index af3f603d6d..dce9cc59a0 100644
--- a/modules/mono/glue/cs_files/ExportAttribute.cs
+++ b/modules/mono/glue/cs_files/ExportAttribute.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace Godot
{
@@ -7,13 +7,11 @@ namespace Godot
{
private int hint;
private string hint_string;
- private int usage;
- public ExportAttribute(int hint = GD.PROPERTY_HINT_NONE, string hint_string = "", int usage = GD.PROPERTY_USAGE_DEFAULT)
+ public ExportAttribute(int hint = GD.PROPERTY_HINT_NONE, string hint_string = "")
{
this.hint = hint;
this.hint_string = hint_string;
- this.usage = usage;
}
}
}
diff --git a/modules/mono/glue/cs_files/MarshalUtils.cs b/modules/mono/glue/cs_files/MarshalUtils.cs
index 5d40111339..2bdfb95c51 100644
--- a/modules/mono/glue/cs_files/MarshalUtils.cs
+++ b/modules/mono/glue/cs_files/MarshalUtils.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace Godot
diff --git a/modules/mono/glue/cs_files/Plane.cs b/modules/mono/glue/cs_files/Plane.cs
index ada6e465ac..37f70aca1e 100644
--- a/modules/mono/glue/cs_files/Plane.cs
+++ b/modules/mono/glue/cs_files/Plane.cs
@@ -1,209 +1,209 @@
-using System;
-
-namespace Godot
-{
- public struct Plane : IEquatable<Plane>
- {
- Vector3 normal;
-
- public float x
- {
- get
- {
- return normal.x;
- }
- set
- {
- normal.x = value;
- }
- }
-
- public float y
- {
- get
- {
- return normal.y;
- }
- set
- {
- normal.y = value;
- }
- }
-
- public float z
- {
- get
- {
- return normal.z;
- }
- set
- {
- normal.z = value;
- }
- }
-
- float d;
-
- public Vector3 Center
- {
- get
- {
- return normal * d;
- }
- }
-
- public float distance_to(Vector3 point)
- {
- return normal.dot(point) - d;
- }
-
- public Vector3 get_any_point()
- {
- return normal * d;
- }
-
- public bool has_point(Vector3 point, float epsilon = Mathf.Epsilon)
- {
- float dist = normal.dot(point) - d;
- return Mathf.abs(dist) <= epsilon;
- }
-
- public Vector3 intersect_3(Plane b, Plane c)
- {
- float denom = normal.cross(b.normal).dot(c.normal);
-
- if (Mathf.abs(denom) <= Mathf.Epsilon)
- return new Vector3();
-
- Vector3 result = (b.normal.cross(c.normal) * this.d) +
- (c.normal.cross(normal) * b.d) +
- (normal.cross(b.normal) * c.d);
-
- return result / denom;
- }
-
- public Vector3 intersect_ray(Vector3 from, Vector3 dir)
- {
- float den = normal.dot(dir);
-
- if (Mathf.abs(den) <= Mathf.Epsilon)
- return new Vector3();
-
- float dist = (normal.dot(from) - d) / den;
-
- // This is a ray, before the emiting pos (from) does not exist
- if (dist > Mathf.Epsilon)
- return new Vector3();
-
- return from + dir * -dist;
- }
-
- public Vector3 intersect_segment(Vector3 begin, Vector3 end)
- {
- Vector3 segment = begin - end;
- float den = normal.dot(segment);
-
- if (Mathf.abs(den) <= Mathf.Epsilon)
- return new Vector3();
-
- float dist = (normal.dot(begin) - d) / den;
-
- if (dist < -Mathf.Epsilon || dist > (1.0f + Mathf.Epsilon))
- return new Vector3();
-
- return begin + segment * -dist;
- }
-
- public bool is_point_over(Vector3 point)
- {
- return normal.dot(point) > d;
- }
-
- public Plane normalized()
- {
- float len = normal.length();
-
- if (len == 0)
- return new Plane(0, 0, 0, 0);
-
- return new Plane(normal / len, d / len);
- }
-
- public Vector3 project(Vector3 point)
- {
- return point - normal * distance_to(point);
- }
-
- public Plane(float a, float b, float c, float d)
- {
- normal = new Vector3(a, b, c);
- this.d = d;
- }
-
- public Plane(Vector3 normal, float d)
- {
- this.normal = normal;
- this.d = d;
- }
-
- public Plane(Vector3 v1, Vector3 v2, Vector3 v3)
- {
- normal = (v1 - v3).cross(v1 - v2);
- normal.normalize();
- d = normal.dot(v1);
- }
-
- public static Plane operator -(Plane plane)
- {
- return new Plane(-plane.normal, -plane.d);
- }
-
- public static bool operator ==(Plane left, Plane right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(Plane left, Plane right)
- {
- return !left.Equals(right);
- }
-
- public override bool Equals(object obj)
- {
- if (obj is Plane)
- {
- return Equals((Plane)obj);
- }
-
- return false;
- }
-
- public bool Equals(Plane other)
- {
- return normal == other.normal && d == other.d;
- }
-
- public override int GetHashCode()
- {
- return normal.GetHashCode() ^ d.GetHashCode();
- }
-
- public override string ToString()
- {
- return String.Format("({0}, {1})", new object[]
- {
- this.normal.ToString(),
- this.d.ToString()
- });
- }
-
- public string ToString(string format)
- {
- return String.Format("({0}, {1})", new object[]
- {
- this.normal.ToString(format),
- this.d.ToString(format)
- });
- }
- }
-}
+using System;
+
+namespace Godot
+{
+ public struct Plane : IEquatable<Plane>
+ {
+ Vector3 normal;
+
+ public float x
+ {
+ get
+ {
+ return normal.x;
+ }
+ set
+ {
+ normal.x = value;
+ }
+ }
+
+ public float y
+ {
+ get
+ {
+ return normal.y;
+ }
+ set
+ {
+ normal.y = value;
+ }
+ }
+
+ public float z
+ {
+ get
+ {
+ return normal.z;
+ }
+ set
+ {
+ normal.z = value;
+ }
+ }
+
+ float d;
+
+ public Vector3 Center
+ {
+ get
+ {
+ return normal * d;
+ }
+ }
+
+ public float distance_to(Vector3 point)
+ {
+ return normal.dot(point) - d;
+ }
+
+ public Vector3 get_any_point()
+ {
+ return normal * d;
+ }
+
+ public bool has_point(Vector3 point, float epsilon = Mathf.Epsilon)
+ {
+ float dist = normal.dot(point) - d;
+ return Mathf.abs(dist) <= epsilon;
+ }
+
+ public Vector3 intersect_3(Plane b, Plane c)
+ {
+ float denom = normal.cross(b.normal).dot(c.normal);
+
+ if (Mathf.abs(denom) <= Mathf.Epsilon)
+ return new Vector3();
+
+ Vector3 result = (b.normal.cross(c.normal) * this.d) +
+ (c.normal.cross(normal) * b.d) +
+ (normal.cross(b.normal) * c.d);
+
+ return result / denom;
+ }
+
+ public Vector3 intersect_ray(Vector3 from, Vector3 dir)
+ {
+ float den = normal.dot(dir);
+
+ if (Mathf.abs(den) <= Mathf.Epsilon)
+ return new Vector3();
+
+ float dist = (normal.dot(from) - d) / den;
+
+ // This is a ray, before the emiting pos (from) does not exist
+ if (dist > Mathf.Epsilon)
+ return new Vector3();
+
+ return from + dir * -dist;
+ }
+
+ public Vector3 intersect_segment(Vector3 begin, Vector3 end)
+ {
+ Vector3 segment = begin - end;
+ float den = normal.dot(segment);
+
+ if (Mathf.abs(den) <= Mathf.Epsilon)
+ return new Vector3();
+
+ float dist = (normal.dot(begin) - d) / den;
+
+ if (dist < -Mathf.Epsilon || dist > (1.0f + Mathf.Epsilon))
+ return new Vector3();
+
+ return begin + segment * -dist;
+ }
+
+ public bool is_point_over(Vector3 point)
+ {
+ return normal.dot(point) > d;
+ }
+
+ public Plane normalized()
+ {
+ float len = normal.length();
+
+ if (len == 0)
+ return new Plane(0, 0, 0, 0);
+
+ return new Plane(normal / len, d / len);
+ }
+
+ public Vector3 project(Vector3 point)
+ {
+ return point - normal * distance_to(point);
+ }
+
+ public Plane(float a, float b, float c, float d)
+ {
+ normal = new Vector3(a, b, c);
+ this.d = d;
+ }
+
+ public Plane(Vector3 normal, float d)
+ {
+ this.normal = normal;
+ this.d = d;
+ }
+
+ public Plane(Vector3 v1, Vector3 v2, Vector3 v3)
+ {
+ normal = (v1 - v3).cross(v1 - v2);
+ normal.normalize();
+ d = normal.dot(v1);
+ }
+
+ public static Plane operator -(Plane plane)
+ {
+ return new Plane(-plane.normal, -plane.d);
+ }
+
+ public static bool operator ==(Plane left, Plane right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Plane left, Plane right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Plane)
+ {
+ return Equals((Plane)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Plane other)
+ {
+ return normal == other.normal && d == other.d;
+ }
+
+ public override int GetHashCode()
+ {
+ return normal.GetHashCode() ^ d.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("({0}, {1})", new object[]
+ {
+ this.normal.ToString(),
+ this.d.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("({0}, {1})", new object[]
+ {
+ this.normal.ToString(format),
+ this.d.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/Rect3.cs b/modules/mono/glue/cs_files/Rect3.cs
index 0d25de1ec6..617d33e7fd 100644
--- a/modules/mono/glue/cs_files/Rect3.cs
+++ b/modules/mono/glue/cs_files/Rect3.cs
@@ -1,477 +1,477 @@
-using System;
-
-// file: core/math/rect3.h
-// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451
-// file: core/math/rect3.cpp
-// commit: bd282ff43f23fe845f29a3e25c8efc01bd65ffb0
-// file: core/variant_call.cpp
-// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685
-
-namespace Godot
-{
- public struct Rect3 : IEquatable<Rect3>
- {
- private Vector3 position;
- private Vector3 size;
-
- public Vector3 Position
- {
- get
- {
- return position;
- }
- }
-
- public Vector3 Size
- {
- get
- {
- return size;
- }
- }
-
- public Vector3 End
- {
- get
- {
- return position + size;
- }
- }
-
- public bool encloses(Rect3 with)
- {
- Vector3 src_min = position;
- Vector3 src_max = position + size;
- Vector3 dst_min = with.position;
- Vector3 dst_max = with.position + with.size;
-
- return ((src_min.x <= dst_min.x) &&
- (src_max.x > dst_max.x) &&
- (src_min.y <= dst_min.y) &&
- (src_max.y > dst_max.y) &&
- (src_min.z <= dst_min.z) &&
- (src_max.z > dst_max.z));
- }
-
- public Rect3 expand(Vector3 to_point)
- {
- Vector3 begin = position;
- Vector3 end = position + size;
-
- if (to_point.x < begin.x)
- begin.x = to_point.x;
- if (to_point.y < begin.y)
- begin.y = to_point.y;
- if (to_point.z < begin.z)
- begin.z = to_point.z;
-
- if (to_point.x > end.x)
- end.x = to_point.x;
- if (to_point.y > end.y)
- end.y = to_point.y;
- if (to_point.z > end.z)
- end.z = to_point.z;
-
- return new Rect3(begin, end - begin);
- }
-
- public float get_area()
- {
- return size.x * size.y * size.z;
- }
-
- public Vector3 get_endpoint(int idx)
- {
- switch (idx)
- {
- case 0:
- return new Vector3(position.x, position.y, position.z);
- case 1:
- return new Vector3(position.x, position.y, position.z + size.z);
- case 2:
- return new Vector3(position.x, position.y + size.y, position.z);
- case 3:
- return new Vector3(position.x, position.y + size.y, position.z + size.z);
- case 4:
- return new Vector3(position.x + size.x, position.y, position.z);
- case 5:
- return new Vector3(position.x + size.x, position.y, position.z + size.z);
- case 6:
- return new Vector3(position.x + size.x, position.y + size.y, position.z);
- case 7:
- return new Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
- default:
- throw new ArgumentOutOfRangeException(nameof(idx), String.Format("Index is {0}, but a value from 0 to 7 is expected.", idx));
- }
- }
-
- public Vector3 get_longest_axis()
- {
- Vector3 axis = new Vector3(1f, 0f, 0f);
- float max_size = size.x;
-
- if (size.y > max_size)
- {
- axis = new Vector3(0f, 1f, 0f);
- max_size = size.y;
- }
-
- if (size.z > max_size)
- {
- axis = new Vector3(0f, 0f, 1f);
- max_size = size.z;
- }
-
- return axis;
- }
-
- public Vector3.Axis get_longest_axis_index()
- {
- Vector3.Axis axis = Vector3.Axis.X;
- float max_size = size.x;
-
- if (size.y > max_size)
- {
- axis = Vector3.Axis.Y;
- max_size = size.y;
- }
-
- if (size.z > max_size)
- {
- axis = Vector3.Axis.Z;
- max_size = size.z;
- }
-
- return axis;
- }
-
- public float get_longest_axis_size()
- {
- float max_size = size.x;
-
- if (size.y > max_size)
- max_size = size.y;
-
- if (size.z > max_size)
- max_size = size.z;
-
- return max_size;
- }
-
- public Vector3 get_shortest_axis()
- {
- Vector3 axis = new Vector3(1f, 0f, 0f);
- float max_size = size.x;
-
- if (size.y < max_size)
- {
- axis = new Vector3(0f, 1f, 0f);
- max_size = size.y;
- }
-
- if (size.z < max_size)
- {
- axis = new Vector3(0f, 0f, 1f);
- max_size = size.z;
- }
-
- return axis;
- }
-
- public Vector3.Axis get_shortest_axis_index()
- {
- Vector3.Axis axis = Vector3.Axis.X;
- float max_size = size.x;
-
- if (size.y < max_size)
- {
- axis = Vector3.Axis.Y;
- max_size = size.y;
- }
-
- if (size.z < max_size)
- {
- axis = Vector3.Axis.Z;
- max_size = size.z;
- }
-
- return axis;
- }
-
- public float get_shortest_axis_size()
- {
- float max_size = size.x;
-
- if (size.y < max_size)
- max_size = size.y;
-
- if (size.z < max_size)
- max_size = size.z;
-
- return max_size;
- }
-
- public Vector3 get_support(Vector3 dir)
- {
- Vector3 half_extents = size * 0.5f;
- Vector3 ofs = position + half_extents;
-
- return ofs + new Vector3(
- (dir.x > 0f) ? -half_extents.x : half_extents.x,
- (dir.y > 0f) ? -half_extents.y : half_extents.y,
- (dir.z > 0f) ? -half_extents.z : half_extents.z);
- }
-
- public Rect3 grow(float by)
- {
- Rect3 res = this;
-
- res.position.x -= by;
- res.position.y -= by;
- res.position.z -= by;
- res.size.x += 2.0f * by;
- res.size.y += 2.0f * by;
- res.size.z += 2.0f * by;
-
- return res;
- }
-
- public bool has_no_area()
- {
- return size.x <= 0f || size.y <= 0f || size.z <= 0f;
- }
-
- public bool has_no_surface()
- {
- return size.x <= 0f && size.y <= 0f && size.z <= 0f;
- }
-
- public bool has_point(Vector3 point)
- {
- if (point.x < position.x)
- return false;
- if (point.y < position.y)
- return false;
- if (point.z < position.z)
- return false;
- if (point.x > position.x + size.x)
- return false;
- if (point.y > position.y + size.y)
- return false;
- if (point.z > position.z + size.z)
- return false;
-
- return true;
- }
-
- public Rect3 intersection(Rect3 with)
- {
- Vector3 src_min = position;
- Vector3 src_max = position + size;
- Vector3 dst_min = with.position;
- Vector3 dst_max = with.position + with.size;
-
- Vector3 min, max;
-
- if (src_min.x > dst_max.x || src_max.x < dst_min.x)
- {
- return new Rect3();
- }
- else
- {
- min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x;
- max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x;
- }
-
- if (src_min.y > dst_max.y || src_max.y < dst_min.y)
- {
- return new Rect3();
- }
- else
- {
- min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y;
- max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y;
- }
-
- if (src_min.z > dst_max.z || src_max.z < dst_min.z)
- {
- return new Rect3();
- }
- else
- {
- min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z;
- max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z;
- }
-
- return new Rect3(min, max - min);
- }
-
- public bool intersects(Rect3 with)
- {
- if (position.x >= (with.position.x + with.size.x))
- return false;
- if ((position.x + size.x) <= with.position.x)
- return false;
- if (position.y >= (with.position.y + with.size.y))
- return false;
- if ((position.y + size.y) <= with.position.y)
- return false;
- if (position.z >= (with.position.z + with.size.z))
- return false;
- if ((position.z + size.z) <= with.position.z)
- return false;
-
- return true;
- }
-
- public bool intersects_plane(Plane plane)
- {
- Vector3[] points =
- {
- new Vector3(position.x, position.y, position.z),
- new Vector3(position.x, position.y, position.z + size.z),
- new Vector3(position.x, position.y + size.y, position.z),
- new Vector3(position.x, position.y + size.y, position.z + size.z),
- new Vector3(position.x + size.x, position.y, position.z),
- new Vector3(position.x + size.x, position.y, position.z + size.z),
- new Vector3(position.x + size.x, position.y + size.y, position.z),
- new Vector3(position.x + size.x, position.y + size.y, position.z + size.z),
- };
-
- bool over = false;
- bool under = false;
-
- for (int i = 0; i < 8; i++)
- {
- if (plane.distance_to(points[i]) > 0)
- over = true;
- else
- under = true;
- }
-
- return under && over;
- }
-
- public bool intersects_segment(Vector3 from, Vector3 to)
- {
- float min = 0f;
- float max = 1f;
-
- for (int i = 0; i < 3; i++)
- {
- float seg_from = from[i];
- float seg_to = to[i];
- float box_begin = position[i];
- float box_end = box_begin + size[i];
- float cmin, cmax;
-
- if (seg_from < seg_to)
- {
- if (seg_from > box_end || seg_to < box_begin)
- return false;
-
- float length = seg_to - seg_from;
- cmin = seg_from < box_begin ? (box_begin - seg_from) / length : 0f;
- cmax = seg_to > box_end ? (box_end - seg_from) / length : 1f;
- }
- else
- {
- if (seg_to > box_end || seg_from < box_begin)
- return false;
-
- float length = seg_to - seg_from;
- cmin = seg_from > box_end ? (box_end - seg_from) / length : 0f;
- cmax = seg_to < box_begin ? (box_begin - seg_from) / length : 1f;
- }
-
- if (cmin > min)
- {
- min = cmin;
- }
-
- if (cmax < max)
- max = cmax;
- if (max < min)
- return false;
- }
-
- return true;
- }
-
- public Rect3 merge(Rect3 with)
- {
- Vector3 beg_1 = position;
- Vector3 beg_2 = with.position;
- Vector3 end_1 = new Vector3(size.x, size.y, size.z) + beg_1;
- Vector3 end_2 = new Vector3(with.size.x, with.size.y, with.size.z) + beg_2;
-
- Vector3 min = new Vector3(
- (beg_1.x < beg_2.x) ? beg_1.x : beg_2.x,
- (beg_1.y < beg_2.y) ? beg_1.y : beg_2.y,
- (beg_1.z < beg_2.z) ? beg_1.z : beg_2.z
- );
-
- Vector3 max = new Vector3(
- (end_1.x > end_2.x) ? end_1.x : end_2.x,
- (end_1.y > end_2.y) ? end_1.y : end_2.y,
- (end_1.z > end_2.z) ? end_1.z : end_2.z
- );
-
- return new Rect3(min, max - min);
- }
-
- public Rect3(Vector3 position, Vector3 size)
- {
- this.position = position;
- this.size = size;
- }
-
- public static bool operator ==(Rect3 left, Rect3 right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(Rect3 left, Rect3 right)
- {
- return !left.Equals(right);
- }
-
- public override bool Equals(object obj)
- {
- if (obj is Rect3)
- {
- return Equals((Rect3)obj);
- }
-
- return false;
- }
-
- public bool Equals(Rect3 other)
- {
- return position == other.position && size == other.size;
- }
-
- public override int GetHashCode()
- {
- return position.GetHashCode() ^ size.GetHashCode();
- }
-
- public override string ToString()
- {
- return String.Format("{0} - {1}", new object[]
- {
- this.position.ToString(),
- this.size.ToString()
- });
- }
-
- public string ToString(string format)
- {
- return String.Format("{0} - {1}", new object[]
- {
- this.position.ToString(format),
- this.size.ToString(format)
- });
- }
- }
-}
+using System;
+
+// file: core/math/rect3.h
+// commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451
+// file: core/math/rect3.cpp
+// commit: bd282ff43f23fe845f29a3e25c8efc01bd65ffb0
+// file: core/variant_call.cpp
+// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685
+
+namespace Godot
+{
+ public struct Rect3 : IEquatable<Rect3>
+ {
+ private Vector3 position;
+ private Vector3 size;
+
+ public Vector3 Position
+ {
+ get
+ {
+ return position;
+ }
+ }
+
+ public Vector3 Size
+ {
+ get
+ {
+ return size;
+ }
+ }
+
+ public Vector3 End
+ {
+ get
+ {
+ return position + size;
+ }
+ }
+
+ public bool encloses(Rect3 with)
+ {
+ Vector3 src_min = position;
+ Vector3 src_max = position + size;
+ Vector3 dst_min = with.position;
+ Vector3 dst_max = with.position + with.size;
+
+ return ((src_min.x <= dst_min.x) &&
+ (src_max.x > dst_max.x) &&
+ (src_min.y <= dst_min.y) &&
+ (src_max.y > dst_max.y) &&
+ (src_min.z <= dst_min.z) &&
+ (src_max.z > dst_max.z));
+ }
+
+ public Rect3 expand(Vector3 to_point)
+ {
+ Vector3 begin = position;
+ Vector3 end = position + size;
+
+ if (to_point.x < begin.x)
+ begin.x = to_point.x;
+ if (to_point.y < begin.y)
+ begin.y = to_point.y;
+ if (to_point.z < begin.z)
+ begin.z = to_point.z;
+
+ if (to_point.x > end.x)
+ end.x = to_point.x;
+ if (to_point.y > end.y)
+ end.y = to_point.y;
+ if (to_point.z > end.z)
+ end.z = to_point.z;
+
+ return new Rect3(begin, end - begin);
+ }
+
+ public float get_area()
+ {
+ return size.x * size.y * size.z;
+ }
+
+ public Vector3 get_endpoint(int idx)
+ {
+ switch (idx)
+ {
+ case 0:
+ return new Vector3(position.x, position.y, position.z);
+ case 1:
+ return new Vector3(position.x, position.y, position.z + size.z);
+ case 2:
+ return new Vector3(position.x, position.y + size.y, position.z);
+ case 3:
+ return new Vector3(position.x, position.y + size.y, position.z + size.z);
+ case 4:
+ return new Vector3(position.x + size.x, position.y, position.z);
+ case 5:
+ return new Vector3(position.x + size.x, position.y, position.z + size.z);
+ case 6:
+ return new Vector3(position.x + size.x, position.y + size.y, position.z);
+ case 7:
+ return new Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
+ default:
+ throw new ArgumentOutOfRangeException(nameof(idx), String.Format("Index is {0}, but a value from 0 to 7 is expected.", idx));
+ }
+ }
+
+ public Vector3 get_longest_axis()
+ {
+ Vector3 axis = new Vector3(1f, 0f, 0f);
+ float max_size = size.x;
+
+ if (size.y > max_size)
+ {
+ axis = new Vector3(0f, 1f, 0f);
+ max_size = size.y;
+ }
+
+ if (size.z > max_size)
+ {
+ axis = new Vector3(0f, 0f, 1f);
+ max_size = size.z;
+ }
+
+ return axis;
+ }
+
+ public Vector3.Axis get_longest_axis_index()
+ {
+ Vector3.Axis axis = Vector3.Axis.X;
+ float max_size = size.x;
+
+ if (size.y > max_size)
+ {
+ axis = Vector3.Axis.Y;
+ max_size = size.y;
+ }
+
+ if (size.z > max_size)
+ {
+ axis = Vector3.Axis.Z;
+ max_size = size.z;
+ }
+
+ return axis;
+ }
+
+ public float get_longest_axis_size()
+ {
+ float max_size = size.x;
+
+ if (size.y > max_size)
+ max_size = size.y;
+
+ if (size.z > max_size)
+ max_size = size.z;
+
+ return max_size;
+ }
+
+ public Vector3 get_shortest_axis()
+ {
+ Vector3 axis = new Vector3(1f, 0f, 0f);
+ float max_size = size.x;
+
+ if (size.y < max_size)
+ {
+ axis = new Vector3(0f, 1f, 0f);
+ max_size = size.y;
+ }
+
+ if (size.z < max_size)
+ {
+ axis = new Vector3(0f, 0f, 1f);
+ max_size = size.z;
+ }
+
+ return axis;
+ }
+
+ public Vector3.Axis get_shortest_axis_index()
+ {
+ Vector3.Axis axis = Vector3.Axis.X;
+ float max_size = size.x;
+
+ if (size.y < max_size)
+ {
+ axis = Vector3.Axis.Y;
+ max_size = size.y;
+ }
+
+ if (size.z < max_size)
+ {
+ axis = Vector3.Axis.Z;
+ max_size = size.z;
+ }
+
+ return axis;
+ }
+
+ public float get_shortest_axis_size()
+ {
+ float max_size = size.x;
+
+ if (size.y < max_size)
+ max_size = size.y;
+
+ if (size.z < max_size)
+ max_size = size.z;
+
+ return max_size;
+ }
+
+ public Vector3 get_support(Vector3 dir)
+ {
+ Vector3 half_extents = size * 0.5f;
+ Vector3 ofs = position + half_extents;
+
+ return ofs + new Vector3(
+ (dir.x > 0f) ? -half_extents.x : half_extents.x,
+ (dir.y > 0f) ? -half_extents.y : half_extents.y,
+ (dir.z > 0f) ? -half_extents.z : half_extents.z);
+ }
+
+ public Rect3 grow(float by)
+ {
+ Rect3 res = this;
+
+ res.position.x -= by;
+ res.position.y -= by;
+ res.position.z -= by;
+ res.size.x += 2.0f * by;
+ res.size.y += 2.0f * by;
+ res.size.z += 2.0f * by;
+
+ return res;
+ }
+
+ public bool has_no_area()
+ {
+ return size.x <= 0f || size.y <= 0f || size.z <= 0f;
+ }
+
+ public bool has_no_surface()
+ {
+ return size.x <= 0f && size.y <= 0f && size.z <= 0f;
+ }
+
+ public bool has_point(Vector3 point)
+ {
+ if (point.x < position.x)
+ return false;
+ if (point.y < position.y)
+ return false;
+ if (point.z < position.z)
+ return false;
+ if (point.x > position.x + size.x)
+ return false;
+ if (point.y > position.y + size.y)
+ return false;
+ if (point.z > position.z + size.z)
+ return false;
+
+ return true;
+ }
+
+ public Rect3 intersection(Rect3 with)
+ {
+ Vector3 src_min = position;
+ Vector3 src_max = position + size;
+ Vector3 dst_min = with.position;
+ Vector3 dst_max = with.position + with.size;
+
+ Vector3 min, max;
+
+ if (src_min.x > dst_max.x || src_max.x < dst_min.x)
+ {
+ return new Rect3();
+ }
+ else
+ {
+ min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x;
+ max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x;
+ }
+
+ if (src_min.y > dst_max.y || src_max.y < dst_min.y)
+ {
+ return new Rect3();
+ }
+ else
+ {
+ min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y;
+ max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y;
+ }
+
+ if (src_min.z > dst_max.z || src_max.z < dst_min.z)
+ {
+ return new Rect3();
+ }
+ else
+ {
+ min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z;
+ max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z;
+ }
+
+ return new Rect3(min, max - min);
+ }
+
+ public bool intersects(Rect3 with)
+ {
+ if (position.x >= (with.position.x + with.size.x))
+ return false;
+ if ((position.x + size.x) <= with.position.x)
+ return false;
+ if (position.y >= (with.position.y + with.size.y))
+ return false;
+ if ((position.y + size.y) <= with.position.y)
+ return false;
+ if (position.z >= (with.position.z + with.size.z))
+ return false;
+ if ((position.z + size.z) <= with.position.z)
+ return false;
+
+ return true;
+ }
+
+ public bool intersects_plane(Plane plane)
+ {
+ Vector3[] points =
+ {
+ new Vector3(position.x, position.y, position.z),
+ new Vector3(position.x, position.y, position.z + size.z),
+ new Vector3(position.x, position.y + size.y, position.z),
+ new Vector3(position.x, position.y + size.y, position.z + size.z),
+ new Vector3(position.x + size.x, position.y, position.z),
+ new Vector3(position.x + size.x, position.y, position.z + size.z),
+ new Vector3(position.x + size.x, position.y + size.y, position.z),
+ new Vector3(position.x + size.x, position.y + size.y, position.z + size.z),
+ };
+
+ bool over = false;
+ bool under = false;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (plane.distance_to(points[i]) > 0)
+ over = true;
+ else
+ under = true;
+ }
+
+ return under && over;
+ }
+
+ public bool intersects_segment(Vector3 from, Vector3 to)
+ {
+ float min = 0f;
+ float max = 1f;
+
+ for (int i = 0; i < 3; i++)
+ {
+ float seg_from = from[i];
+ float seg_to = to[i];
+ float box_begin = position[i];
+ float box_end = box_begin + size[i];
+ float cmin, cmax;
+
+ if (seg_from < seg_to)
+ {
+ if (seg_from > box_end || seg_to < box_begin)
+ return false;
+
+ float length = seg_to - seg_from;
+ cmin = seg_from < box_begin ? (box_begin - seg_from) / length : 0f;
+ cmax = seg_to > box_end ? (box_end - seg_from) / length : 1f;
+ }
+ else
+ {
+ if (seg_to > box_end || seg_from < box_begin)
+ return false;
+
+ float length = seg_to - seg_from;
+ cmin = seg_from > box_end ? (box_end - seg_from) / length : 0f;
+ cmax = seg_to < box_begin ? (box_begin - seg_from) / length : 1f;
+ }
+
+ if (cmin > min)
+ {
+ min = cmin;
+ }
+
+ if (cmax < max)
+ max = cmax;
+ if (max < min)
+ return false;
+ }
+
+ return true;
+ }
+
+ public Rect3 merge(Rect3 with)
+ {
+ Vector3 beg_1 = position;
+ Vector3 beg_2 = with.position;
+ Vector3 end_1 = new Vector3(size.x, size.y, size.z) + beg_1;
+ Vector3 end_2 = new Vector3(with.size.x, with.size.y, with.size.z) + beg_2;
+
+ Vector3 min = new Vector3(
+ (beg_1.x < beg_2.x) ? beg_1.x : beg_2.x,
+ (beg_1.y < beg_2.y) ? beg_1.y : beg_2.y,
+ (beg_1.z < beg_2.z) ? beg_1.z : beg_2.z
+ );
+
+ Vector3 max = new Vector3(
+ (end_1.x > end_2.x) ? end_1.x : end_2.x,
+ (end_1.y > end_2.y) ? end_1.y : end_2.y,
+ (end_1.z > end_2.z) ? end_1.z : end_2.z
+ );
+
+ return new Rect3(min, max - min);
+ }
+
+ public Rect3(Vector3 position, Vector3 size)
+ {
+ this.position = position;
+ this.size = size;
+ }
+
+ public static bool operator ==(Rect3 left, Rect3 right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Rect3 left, Rect3 right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Rect3)
+ {
+ return Equals((Rect3)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Rect3 other)
+ {
+ return position == other.position && size == other.size;
+ }
+
+ public override int GetHashCode()
+ {
+ return position.GetHashCode() ^ size.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0} - {1}", new object[]
+ {
+ this.position.ToString(),
+ this.size.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("{0} - {1}", new object[]
+ {
+ this.position.ToString(format),
+ this.size.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/ToolAttribute.cs b/modules/mono/glue/cs_files/ToolAttribute.cs
index 0275982c7f..d8601b5b32 100644
--- a/modules/mono/glue/cs_files/ToolAttribute.cs
+++ b/modules/mono/glue/cs_files/ToolAttribute.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace Godot
{
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 0a2010e99d..7cc2168b70 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -33,6 +33,7 @@
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
+#include "os/dir_access.h"
#include "project_settings.h"
#include "version.h"
#endif
@@ -60,12 +61,20 @@ String _get_mono_user_dir() {
} else {
String settings_path;
- if (OS::get_singleton()->has_environment("APPDATA")) {
- String app_data = OS::get_singleton()->get_environment("APPDATA").replace("\\", "/");
- settings_path = app_data.plus_file(String(_MKSTR(VERSION_SHORT_NAME)).capitalize());
- } else if (OS::get_singleton()->has_environment("HOME")) {
- String home = OS::get_singleton()->get_environment("HOME");
- settings_path = home.plus_file("." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower());
+ String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir();
+ DirAccessRef d = DirAccess::create_for_path(exe_dir);
+
+ if (d->file_exists("._sc_") || d->file_exists("_sc_")) {
+ // contain yourself
+ settings_path = exe_dir.plus_file("editor_data");
+ } else {
+ if (OS::get_singleton()->has_environment("APPDATA")) {
+ String app_data = OS::get_singleton()->get_environment("APPDATA").replace("\\", "/");
+ settings_path = app_data.plus_file(String(_MKSTR(VERSION_SHORT_NAME)).capitalize());
+ } else if (OS::get_singleton()->has_environment("HOME")) {
+ String home = OS::get_singleton()->get_environment("HOME");
+ settings_path = home.plus_file("." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower());
+ }
}
return settings_path.plus_file("mono");
@@ -113,7 +122,14 @@ private:
#ifdef TOOLS_ENABLED
mono_solutions_dir = mono_user_dir.plus_file("solutions");
build_logs_dir = mono_user_dir.plus_file("build_logs");
- String base_path = String("res://") + ProjectSettings::get_singleton()->get("application/config/name");
+
+ String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
+
+ String base_path = String("res://") + name;
+
sln_filepath = ProjectSettings::get_singleton()->globalize_path(base_path + ".sln");
csproj_filepath = ProjectSettings::get_singleton()->globalize_path(base_path + ".csproj");
#endif
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index d3ad968135..e10e06df0e 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -59,6 +59,10 @@ Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) {
void MonoGCHandle::release() {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(GDMono::get_singleton() == NULL);
+#endif
+
if (!released && GDMono::get_singleton()->is_runtime_initialized()) {
mono_gchandle_free(handle);
released = true;
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 98b57adc50..c997b0f000 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "gd_mono.h"
+#include <mono/metadata/exception.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/mono-gc.h>
@@ -47,6 +48,15 @@
#include "../editor/godotsharp_editor.h"
#endif
+void gdmono_unhandled_exception_hook(MonoObject *exc, void *user_data) {
+
+ (void)user_data; // UNUSED
+
+ ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8());
+ mono_print_unhandled_exception(exc);
+ abort();
+}
+
#ifdef MONO_PRINT_HANDLER_ENABLED
void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) {
@@ -132,7 +142,7 @@ void GDMono::initialize() {
ERR_FAIL_NULL(Engine::get_singleton());
- OS::get_singleton()->print("Initializing mono...\n");
+ OS::get_singleton()->print("Mono: Initializing module...\n");
#ifdef DEBUG_METHODS_ENABLED
_initialize_and_check_api_hashes();
@@ -214,7 +224,9 @@ void GDMono::initialize() {
// The following assemblies are not required at initialization
_load_all_script_assemblies();
- OS::get_singleton()->print("Mono: EVERYTHING OK\n");
+ mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL);
+
+ OS::get_singleton()->print("Mono: ALL IS GOOD\n");
}
#ifndef MONO_GLUE_DISABLED
@@ -357,9 +369,12 @@ bool GDMono::_load_project_assembly() {
if (project_assembly)
return true;
- String project_assembly_name = ProjectSettings::get_singleton()->get("application/config/name");
+ String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
- bool success = _load_assembly(project_assembly_name, &project_assembly);
+ bool success = _load_assembly(name, &project_assembly);
if (success)
mono_assembly_set_main(project_assembly->get_assembly());
@@ -610,6 +625,8 @@ GDMono::~GDMono() {
if (gdmono_log)
memdelete(gdmono_log);
+
+ singleton = NULL;
}
_GodotSharp *_GodotSharp::singleton = NULL;
@@ -688,7 +705,7 @@ bool _GodotSharp::is_domain_loaded() {
void _GodotSharp::queue_dispose(Object *p_object) {
- if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+ if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
_dispose_object(p_object);
} else {
#ifndef NO_THREADS
@@ -705,7 +722,7 @@ void _GodotSharp::queue_dispose(Object *p_object) {
void _GodotSharp::queue_dispose(NodePath *p_node_path) {
- if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+ if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
memdelete(p_node_path);
} else {
#ifndef NO_THREADS
@@ -722,7 +739,7 @@ void _GodotSharp::queue_dispose(NodePath *p_node_path) {
void _GodotSharp::queue_dispose(RID *p_rid) {
- if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+ if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
memdelete(p_rid);
} else {
#ifndef NO_THREADS
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 4b370295f3..7dc7043eec 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -95,7 +95,9 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
(void)user_data; // UNUSED
if (search_dirs.empty()) {
+#ifdef TOOLS_DOMAIN
search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir());
+#endif
search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
search_dirs.push_back(OS::get_singleton()->get_resource_dir());
search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir());
@@ -105,10 +107,11 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5"));
}
- while (assemblies_path) {
- if (*assemblies_path)
+ if (assemblies_path) {
+ while (*assemblies_path) {
search_dirs.push_back(*assemblies_path);
- ++assemblies_path;
+ ++assemblies_path;
+ }
}
}
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 0134ace5d7..77ba0ee90e 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -43,6 +43,14 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
return mono_class_is_assignable_from(mono_class, p_from->mono_class);
}
+String GDMonoClass::get_full_name() const {
+
+ String res = namespace_name;
+ if (res.length())
+ res += ".";
+ return res + class_name;
+}
+
GDMonoClass *GDMonoClass::get_parent_class() {
if (assembly) {
@@ -56,6 +64,30 @@ GDMonoClass *GDMonoClass::get_parent_class() {
return NULL;
}
+#ifdef TOOLS_ENABLED
+Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
+
+ bool class_is_enum = mono_class_is_enum(mono_class);
+ ERR_FAIL_COND_V(!class_is_enum, Vector<MonoClassField *>());
+
+ Vector<MonoClassField *> enum_fields;
+
+ void *iter = NULL;
+ MonoClassField *raw_field = NULL;
+ while ((raw_field = mono_class_get_fields(get_raw(), &iter)) != NULL) {
+ uint32_t field_flags = mono_field_get_flags(raw_field);
+
+ // Enums have an instance field named value__ which holds the value of the enum.
+ // Enum constants are static, so we will use this to ignore the value__ field.
+ if (field_flags & MONO_FIELD_ATTR_PUBLIC && field_flags & MONO_FIELD_ATTR_STATIC) {
+ enum_fields.push_back(raw_field);
+ }
+ }
+
+ return enum_fields;
+}
+#endif
+
bool GDMonoClass::has_method(const StringName &p_name) {
return get_method(p_name) != NULL;
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 1e72553879..ef1ca425a7 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -98,8 +98,14 @@ public:
_FORCE_INLINE_ MonoClass *get_raw() const { return mono_class; }
_FORCE_INLINE_ const GDMonoAssembly *get_assembly() const { return assembly; }
+ String get_full_name() const;
+
GDMonoClass *get_parent_class();
+#ifdef TOOLS_ENABLED
+ Vector<MonoClassField *> get_enum_fields();
+#endif
+
bool has_method(const StringName &p_name);
bool has_attribute(GDMonoClass *p_attr_class);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index c2d8eeaa32..1643f8cfc5 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -51,6 +51,7 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
{ \
m_type val = p_value.operator m_type(); \
mono_field_set_value(p_object, mono_field, &val); \
+ break; \
}
#define SET_FROM_ARRAY_AND_BREAK(m_type) \
@@ -137,6 +138,9 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
if (tclass == CACHED_CLASS(Plane))
SET_FROM_STRUCT_AND_BREAK(Plane);
+ if (mono_class_is_enum(tclass->get_raw()))
+ SET_FROM_PRIMITIVE(signed int);
+
ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());
ERR_FAIL();
} break;
@@ -179,19 +183,19 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
// GodotObject
if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
break;
}
if (CACHED_CLASS(NodePath) == type_class) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
break;
}
if (CACHED_CLASS(RID) == type_class) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
break;
}
@@ -200,8 +204,6 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
} break;
case MONO_TYPE_OBJECT: {
- GDMonoClass *type_class = type.type_class;
-
// Variant
switch (p_value.get_type()) {
case Variant::BOOL: {
@@ -233,11 +235,11 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
case Variant::COLOR: SET_FROM_STRUCT_AND_BREAK(Color);
case Variant::NODE_PATH: {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::_RID: {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::OBJECT: {
MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
@@ -246,7 +248,7 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
}
case Variant::DICTIONARY: {
MonoObject *managed = GDMonoMarshal::Dictionary_to_mono_object(p_value.operator Dictionary());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::ARRAY: SET_FROM_ARRAY_AND_BREAK(Array);
case Variant::POOL_BYTE_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolByteArray);
@@ -264,7 +266,7 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
case MONO_TYPE_GENERICINST: {
if (CACHED_RAW_MONO_CLASS(Dictionary) == type.type_class->get_raw()) {
MonoObject *managed = GDMonoMarshal::Dictionary_to_mono_object(p_value.operator Dictionary());
- mono_field_set_value(p_object, mono_field, &managed);
+ mono_field_set_value(p_object, mono_field, managed);
break;
}
} break;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 9a6c8f0cd6..01392447f3 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -112,6 +112,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
if (tclass == CACHED_CLASS(Plane))
return Variant::PLANE;
+
+ if (mono_class_is_enum(tclass->get_raw()))
+ return Variant::INT;
} break;
case MONO_TYPE_ARRAY:
@@ -165,9 +168,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::DICTIONARY;
}
} break;
+
+ default: {
+ } break;
}
- // No error, the caller will decide what to do in this case
+ // Unknown
return Variant::NIL;
}
@@ -299,6 +305,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (tclass == CACHED_CLASS(Plane))
RETURN_BOXED_STRUCT(Plane, p_var);
+
+ if (mono_class_is_enum(tclass->get_raw())) {
+ int val = p_var->operator signed int();
+ return BOX_ENUM(tclass->get_raw(), val);
+ }
} break;
case MONO_TYPE_ARRAY:
@@ -515,6 +526,9 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
if (tclass == CACHED_CLASS(Plane))
RETURN_UNBOXED_STRUCT(Plane, p_obj);
+
+ if (mono_class_is_enum(tclass->get_raw()))
+ return unbox<int32_t>(p_obj);
} break;
case MONO_TYPE_ARRAY:
@@ -586,7 +600,7 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
for (int i = 0; i < p_array.size(); i++) {
MonoObject *boxed = variant_to_mono_object(p_array[i]);
- mono_array_set(ret, MonoObject *, i, boxed);
+ mono_array_setref(ret, i, boxed);
}
return ret;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 38dd22357d..9f403b787f 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -53,6 +53,7 @@ T unbox(MonoObject *p_obj) {
#define BOX_UINT8(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), &x)
#define BOX_BOOLEAN(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(bool), &x)
#define BOX_PTR(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(IntPtr), x)
+#define BOX_ENUM(m_enum_class, x) mono_value_box(mono_domain_get(), m_enum_class, &x)
Variant::Type managed_to_variant_type(const ManagedType &p_type);
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index 6468e0d3d9..eb97d62900 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -83,9 +83,32 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params,
mono_array_set(params, MonoObject *, i, boxed_param);
}
- return mono_runtime_invoke_array(mono_method, p_object, params, r_exc);
+ MonoObject *exc = NULL;
+ MonoObject *ret = mono_runtime_invoke_array(mono_method, p_object, params, &exc);
+
+ if (exc) {
+ if (r_exc) {
+ *r_exc = exc;
+ } else {
+ ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8());
+ mono_print_unhandled_exception(exc);
+ }
+ }
+
+ return ret;
} else {
- mono_runtime_invoke(mono_method, p_object, NULL, r_exc);
+ MonoObject *exc = NULL;
+ mono_runtime_invoke(mono_method, p_object, NULL, &exc);
+
+ if (exc) {
+ if (r_exc) {
+ *r_exc = exc;
+ } else {
+ ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8());
+ mono_print_unhandled_exception(exc);
+ }
+ }
+
return NULL;
}
}
@@ -96,7 +119,19 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoObject **r_exc) {
}
MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoObject **r_exc) {
- return mono_runtime_invoke(mono_method, p_object, p_params, r_exc);
+ MonoObject *exc = NULL;
+ MonoObject *ret = mono_runtime_invoke(mono_method, p_object, p_params, &exc);
+
+ if (exc) {
+ if (r_exc) {
+ *r_exc = exc;
+ } else {
+ ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8());
+ mono_print_unhandled_exception(exc);
+ }
+ }
+
+ return ret;
}
bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 5deca8e64d..53e45002c4 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -86,6 +86,7 @@ void MonoCache::clear_members() {
class_NodePath = NULL;
class_RID = NULL;
class_GodotObject = NULL;
+ class_GodotReference = NULL;
class_Node = NULL;
class_Control = NULL;
class_Spatial = NULL;
@@ -95,7 +96,6 @@ void MonoCache::clear_members() {
class_ExportAttribute = NULL;
field_ExportAttribute_hint = NULL;
field_ExportAttribute_hint_string = NULL;
- field_ExportAttribute_usage = NULL;
class_ToolAttribute = NULL;
class_RemoteAttribute = NULL;
class_SyncAttribute = NULL;
@@ -111,7 +111,7 @@ void MonoCache::clear_members() {
methodthunk_MarshalUtils_DictionaryToArrays = NULL;
methodthunk_MarshalUtils_ArraysToDictionary = NULL;
- methodthunk_GodotObject__AwaitedSignalCallback = NULL;
+ methodthunk_SignalAwaiter_SignalCallback = NULL;
methodthunk_SignalAwaiter_FailureCallback = NULL;
methodthunk_GodotTaskScheduler_Activate = NULL;
@@ -153,6 +153,7 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath));
CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(NodePath));
CACHE_CLASS_AND_CHECK(GodotObject, GODOT_API_CLASS(Object));
+ CACHE_CLASS_AND_CHECK(GodotReference, GODOT_API_CLASS(Reference));
CACHE_CLASS_AND_CHECK(Node, GODOT_API_CLASS(Node));
CACHE_CLASS_AND_CHECK(Control, GODOT_API_CLASS(Control));
CACHE_CLASS_AND_CHECK(Spatial, GODOT_API_CLASS(Spatial));
@@ -163,7 +164,6 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(ExportAttribute, GODOT_API_CLASS(ExportAttribute));
CACHE_FIELD_AND_CHECK(ExportAttribute, hint, CACHED_CLASS(ExportAttribute)->get_field("hint"));
CACHE_FIELD_AND_CHECK(ExportAttribute, hint_string, CACHED_CLASS(ExportAttribute)->get_field("hint_string"));
- CACHE_FIELD_AND_CHECK(ExportAttribute, usage, CACHED_CLASS(ExportAttribute)->get_field("usage"));
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute));
@@ -178,7 +178,7 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryToArrays, (MarshalUtils_DictToArrays)CACHED_CLASS(MarshalUtils)->get_method("DictionaryToArrays", 3)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArraysToDictionary, (MarshalUtils_ArraysToDict)CACHED_CLASS(MarshalUtils)->get_method("ArraysToDictionary", 2)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(GodotObject, _AwaitedSignalCallback, (GodotObject__AwaitedSignalCallback)CACHED_CLASS(GodotObject)->get_method("_AwaitedSignalCallback", 2)->get_thunk());
+ CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, (SignalAwaiter_SignalCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)->get_thunk());
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index f97f048aa9..ebb5d28e4d 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -42,7 +42,7 @@ namespace GDMonoUtils {
typedef MonoObject *(*MarshalUtils_DictToArrays)(MonoObject *, MonoArray **, MonoArray **, MonoObject **);
typedef MonoObject *(*MarshalUtils_ArraysToDict)(MonoArray *, MonoArray *, MonoObject **);
-typedef MonoObject *(*GodotObject__AwaitedSignalCallback)(MonoObject *, MonoArray **, MonoObject *, MonoObject **);
+typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray **, MonoObject **);
typedef MonoObject *(*SignalAwaiter_FailureCallback)(MonoObject *, MonoObject **);
typedef MonoObject *(*GodotTaskScheduler_Activate)(MonoObject *, MonoObject **);
@@ -88,6 +88,7 @@ struct MonoCache {
GDMonoClass *class_NodePath;
GDMonoClass *class_RID;
GDMonoClass *class_GodotObject;
+ GDMonoClass *class_GodotReference;
GDMonoClass *class_Node;
GDMonoClass *class_Control;
GDMonoClass *class_Spatial;
@@ -97,7 +98,6 @@ struct MonoCache {
GDMonoClass *class_ExportAttribute;
GDMonoField *field_ExportAttribute_hint;
GDMonoField *field_ExportAttribute_hint_string;
- GDMonoField *field_ExportAttribute_usage;
GDMonoClass *class_ToolAttribute;
GDMonoClass *class_RemoteAttribute;
GDMonoClass *class_SyncAttribute;
@@ -113,7 +113,7 @@ struct MonoCache {
MarshalUtils_DictToArrays methodthunk_MarshalUtils_DictionaryToArrays;
MarshalUtils_ArraysToDict methodthunk_MarshalUtils_ArraysToDictionary;
- GodotObject__AwaitedSignalCallback methodthunk_GodotObject__AwaitedSignalCallback;
+ SignalAwaiter_SignalCallback methodthunk_SignalAwaiter_SignalCallback;
SignalAwaiter_FailureCallback methodthunk_SignalAwaiter_FailureCallback;
GodotTaskScheduler_Activate methodthunk_GodotTaskScheduler_Activate;
@@ -149,6 +149,10 @@ void attach_current_thread();
void detach_current_thread();
MonoThread *get_current_thread();
+_FORCE_INLINE_ bool is_main_thread() {
+ return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current();
+}
+
GDMonoClass *get_object_class(MonoObject *p_object);
GDMonoClass *type_get_proxy_class(const StringName &p_type);
GDMonoClass *get_class_native_base(GDMonoClass *p_class);
@@ -164,7 +168,7 @@ String get_exception_name_and_message(MonoObject *p_ex);
} // GDMonoUtils
-#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field("nativeName")->get_value(NULL)))
+#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL)))
#define CACHED_CLASS(m_class) (GDMonoUtils::mono_cache.class_##m_class)
#define CACHED_CLASS_RAW(m_class) (GDMonoUtils::mono_cache.class_##m_class->get_raw())
diff --git a/modules/mono/mono_reg_utils.py b/modules/mono/mono_reg_utils.py
index e9988625f5..8ddddb3a24 100644
--- a/modules/mono/mono_reg_utils.py
+++ b/modules/mono/mono_reg_utils.py
@@ -1,4 +1,7 @@
import os
+import platform
+
+from compat import decode_utf8
if os.name == 'nt':
import sys
@@ -11,8 +14,7 @@ if os.name == 'nt':
def _reg_open_key(key, subkey):
try:
return winreg.OpenKey(key, subkey)
- except (WindowsError, EnvironmentError) as e:
- import platform
+ except (WindowsError, OSError):
if platform.architecture()[0] == '32bit':
bitness_sam = winreg.KEY_WOW64_64KEY
else:
@@ -20,39 +22,93 @@ def _reg_open_key(key, subkey):
return winreg.OpenKey(key, subkey, 0, winreg.KEY_READ | bitness_sam)
-def _find_mono_in_reg(subkey):
+def _reg_open_key_bits(key, subkey, bits):
+ sam = winreg.KEY_READ
+
+ if platform.architecture()[0] == '32bit':
+ if bits == '64':
+ # Force 32bit process to search in 64bit registry
+ sam |= winreg.KEY_WOW64_64KEY
+ else:
+ if bits == '32':
+ # Force 64bit process to search in 32bit registry
+ sam |= winreg.KEY_WOW64_32KEY
+
+ return winreg.OpenKey(key, subkey, 0, sam)
+
+
+def _find_mono_in_reg(subkey, bits):
try:
- with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
+ with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
value, regtype = winreg.QueryValueEx(hKey, 'SdkInstallRoot')
return value
- except (WindowsError, EnvironmentError) as e:
+ except (WindowsError, OSError):
return None
-def _find_mono_in_reg_old(subkey):
+
+def _find_mono_in_reg_old(subkey, bits):
try:
- with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
+ with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
default_clr, regtype = winreg.QueryValueEx(hKey, 'DefaultCLR')
if default_clr:
- return _find_mono_in_reg(subkey + '\\' + default_clr)
+ return _find_mono_in_reg(subkey + '\\' + default_clr, bits)
return None
except (WindowsError, EnvironmentError):
return None
-def find_mono_root_dir():
- dir = _find_mono_in_reg(r'SOFTWARE\Mono')
- if dir:
- return dir
- dir = _find_mono_in_reg_old(r'SOFTWARE\Novell\Mono')
- if dir:
- return dir
- return None
+def find_mono_root_dir(bits):
+ root_dir = _find_mono_in_reg(r'SOFTWARE\Mono', bits)
+ if root_dir is not None:
+ return root_dir
+ root_dir = _find_mono_in_reg_old(r'SOFTWARE\Novell\Mono', bits)
+ if root_dir is not None:
+ return root_dir
+ return ''
def find_msbuild_tools_path_reg():
+ import subprocess
+
+ vswhere = os.getenv('PROGRAMFILES(X86)')
+ if not vswhere:
+ vswhere = os.getenv('PROGRAMFILES')
+ vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'
+
+ vswhere_args = ['-latest', '-requires', 'Microsoft.Component.MSBuild']
+
try:
- with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0') as hKey:
+ lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()
+
+ for line in lines:
+ parts = decode_utf8(line).split(':', 1)
+
+ if len(parts) < 2 or parts[0] != 'installationPath':
+ continue
+
+ val = parts[1].strip()
+
+ if not val:
+ raise ValueError('Value of `installationPath` entry is empty')
+
+ return os.path.join(val, "MSBuild\\15.0\\Bin")
+
+ raise ValueError('Cannot find `installationPath` entry')
+ except ValueError as e:
+ print('Error reading output from vswhere: ' + e.message)
+ except WindowsError:
+ pass # Fine, vswhere not found
+ except (subprocess.CalledProcessError, OSError):
+ pass
+
+ # Try to find 14.0 in the Registry
+
+ try:
+ subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
+ with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
value, regtype = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')
return value
- except (WindowsError, EnvironmentError) as e:
- return None
+ except (WindowsError, OSError):
+ return ''
+
+ return ''
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index 012dd119b1..7e99df29a1 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -29,6 +29,9 @@
/*************************************************************************/
#include "signal_awaiter_utils.h"
+#include "csharp_script.h"
+#include "mono_gd/gd_mono_class.h"
+#include "mono_gd/gd_mono_marshal.h"
#include "mono_gd/gd_mono_utils.h"
namespace SignalAwaiterUtils {
@@ -40,13 +43,20 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
uint32_t awaiter_handle = MonoGCHandle::make_strong_handle(p_awaiter);
Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(awaiter_handle));
+#ifdef DEBUG_ENABLED
+ sa_con->set_connection_target(p_target);
+#endif
+
Vector<Variant> binds;
binds.push_back(sa_con);
- Error err = p_source->connect(p_signal, p_target, "_AwaitedSignalCallback", binds, Object::CONNECT_ONESHOT);
+
+ Error err = p_source->connect(p_signal, sa_con.ptr(),
+ CSharpLanguage::get_singleton()->get_string_names()._signal_callback,
+ binds, Object::CONNECT_ONESHOT);
if (err != OK) {
- // set it as completed to prevent it from calling the failure callback when deleted
- // the awaiter will be aware of the failure by checking the returned error
+ // Set it as completed to prevent it from calling the failure callback when released.
+ // The awaiter will be aware of the failure by checking the returned error.
sa_con->set_completed(true);
}
@@ -54,11 +64,68 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
}
}
-SignalAwaiterHandle::SignalAwaiterHandle(uint32_t p_handle)
- : MonoGCHandle(p_handle) {
+Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+
+#ifdef DEBUG_ENABLED
+ if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) {
+ ERR_EXPLAIN("Resumed after await, but class instance is gone");
+ ERR_FAIL_V(Variant());
+ }
+#endif
+
+ if (p_argcount < 1) {
+ r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = 1;
+ return Variant();
+ }
+
+ Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1];
+
+ if (self.is_null()) {
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = p_argcount - 1;
+ r_error.expected = Variant::OBJECT;
+ return Variant();
+ }
+
+ set_completed(true);
+
+ int signal_argc = p_argcount - 1;
+ MonoArray *signal_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), signal_argc);
+
+ for (int i = 0; i < signal_argc; i++) {
+ MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
+ mono_array_set(signal_args, MonoObject *, i, boxed);
+ }
+
+ GDMonoUtils::SignalAwaiter_SignalCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback);
+
+ MonoObject *ex = NULL;
+ thunk(get_target(), &signal_args, &ex);
+
+ if (ex) {
+ mono_print_unhandled_exception(ex);
+ ERR_FAIL_V(Variant());
+ }
+
+ return Variant();
+}
+
+void SignalAwaiterHandle::_bind_methods() {
+
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &SignalAwaiterHandle::_signal_callback, MethodInfo("_signal_callback"));
+}
+
+SignalAwaiterHandle::SignalAwaiterHandle(uint32_t p_managed_handle)
+ : MonoGCHandle(p_managed_handle) {
+
+#ifdef DEBUG_ENABLED
+ conn_target_id = 0;
+#endif
}
SignalAwaiterHandle::~SignalAwaiterHandle() {
+
if (!completed) {
GDMonoUtils::SignalAwaiter_FailureCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, FailureCallback);
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index 422ed4754f..0d615b5826 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -40,13 +40,30 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
class SignalAwaiterHandle : public MonoGCHandle {
+ GDCLASS(SignalAwaiterHandle, MonoGCHandle)
+
bool completed;
+#ifdef DEBUG_ENABLED
+ ObjectID conn_target_id;
+#endif
+
+ Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+
+protected:
+ static void _bind_methods();
+
public:
_FORCE_INLINE_ bool is_completed() { return completed; }
_FORCE_INLINE_ void set_completed(bool p_completed) { completed = p_completed; }
- SignalAwaiterHandle(uint32_t p_handle);
+#ifdef DEBUG_ENABLED
+ _FORCE_INLINE_ void set_connection_target(Object *p_target) {
+ conn_target_id = p_target->get_instance_id();
+ }
+#endif
+
+ SignalAwaiterHandle(uint32_t p_managed_handle);
~SignalAwaiterHandle();
};
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index c8581f6122..105c2c981e 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -56,9 +56,6 @@ String path_which(const String &p_name) {
for (int i = 0; i < env_path.size(); i++) {
String p = path_join(env_path[i], p_name);
- if (FileAccess::exists(p))
- return p;
-
#ifdef WINDOWS_ENABLED
for (int j = 0; j < exts.size(); j++) {
String p2 = p + exts[j];
@@ -66,6 +63,9 @@ String path_which(const String &p_name) {
if (FileAccess::exists(p2))
return p2;
}
+#else
+ if (FileAccess::exists(p))
+ return p;
#endif
}
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index de1a60dbd1..f26663ea11 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -126,3 +126,32 @@ String sformat(const String &p_text, const Variant &p1, const Variant &p2, const
return new_string;
}
+
+bool is_csharp_keyword(const String &p_name) {
+
+ // Reserved keywords
+
+ return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" ||
+ p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" ||
+ p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" ||
+ p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" ||
+ p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" ||
+ p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" ||
+ p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" ||
+ p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" ||
+ p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" ||
+ p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" ||
+ p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" ||
+ p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" ||
+ p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" ||
+ p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" ||
+ p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" ||
+ p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" ||
+ p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" ||
+ p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" ||
+ p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while";
+}
+
+String escape_csharp_keyword(const String &p_name) {
+ return is_csharp_keyword(p_name) ? "@" + p_name : p_name;
+}
diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h
index 2f2c3c2d89..a0d66ebdc3 100644
--- a/modules/mono/utils/string_utils.h
+++ b/modules/mono/utils/string_utils.h
@@ -35,4 +35,10 @@
String sformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
+#ifdef TOOLS_ENABLED
+bool is_csharp_keyword(const String &p_name);
+
+String escape_csharp_keyword(const String &p_name);
+#endif
+
#endif // STRING_FORMAT_H
diff --git a/modules/openssl/stream_peer_openssl.cpp b/modules/openssl/stream_peer_openssl.cpp
index c19bdc4214..6d1d5485f3 100644
--- a/modules/openssl/stream_peer_openssl.cpp
+++ b/modules/openssl/stream_peer_openssl.cpp
@@ -30,7 +30,7 @@
#include "stream_peer_openssl.h"
// Compatibility with OpenSSL 1.1.0.
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
#define BIO_set_num(b, n)
#else
#define BIO_set_num(b, n) ((b)->num = (n))
@@ -269,7 +269,7 @@ int StreamPeerOpenSSL::_bio_puts(BIO *b, const char *str) {
return _bio_write(b, str, strlen(str));
}
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
BIO_METHOD *StreamPeerOpenSSL::_bio_method = NULL;
BIO_METHOD *StreamPeerOpenSSL::_get_bio_method() {
@@ -568,7 +568,7 @@ void StreamPeerOpenSSL::initialize_ssl() {
load_certs_func = _load_certs;
_create = _create_func;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
#endif
SSL_library_init(); // Initialize OpenSSL's SSL libraries
diff --git a/modules/openssl/stream_peer_openssl.h b/modules/openssl/stream_peer_openssl.h
index 535114058d..ad09564447 100644
--- a/modules/openssl/stream_peer_openssl.h
+++ b/modules/openssl/stream_peer_openssl.h
@@ -53,7 +53,7 @@ private:
static int _bio_gets(BIO *b, char *buf, int len);
static int _bio_puts(BIO *b, const char *str);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
static BIO_METHOD *_bio_method;
#else
static BIO_METHOD _bio_method;
diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
index c7748b9b21..06eab4c94d 100644
--- a/modules/opus/audio_stream_opus.cpp
+++ b/modules/opus/audio_stream_opus.cpp
@@ -267,7 +267,7 @@ void AudioStreamPlaybackOpus::seek(float p_time) {
frames_mixed = osrate * p_time;
}
-int AudioStreamPlaybackOpus::mix(int16_t *p_bufer, int p_frames) {
+int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) {
if (!playing)
return 0;
@@ -281,7 +281,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_bufer, int p_frames) {
break;
}
- int ret = op_read(opus_file, (opus_int16 *)p_bufer, todo * stream_channels, &current_section);
+ int ret = op_read(opus_file, (opus_int16 *)p_buffer, todo * stream_channels, &current_section);
if (ret < 0) {
playing = false;
ERR_EXPLAIN("Error reading Opus File: " + file);
@@ -325,7 +325,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_bufer, int p_frames) {
frames_mixed += ret;
- p_bufer += ret * stream_channels;
+ p_buffer += ret * stream_channels;
p_frames -= ret;
}
diff --git a/modules/opus/audio_stream_opus.h b/modules/opus/audio_stream_opus.h
index 7b7740a804..f8d8f585cf 100644
--- a/modules/opus/audio_stream_opus.h
+++ b/modules/opus/audio_stream_opus.h
@@ -107,7 +107,7 @@ public:
virtual int get_minimum_buffer_size() const;
- virtual int mix(int16_t *p_bufer, int p_frames);
+ virtual int mix(int16_t *p_buffer, int p_frames);
AudioStreamPlaybackOpus();
~AudioStreamPlaybackOpus();
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index 2bab144a28..18b4051afe 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -8,7 +8,7 @@ env_regex.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=0"])
env_regex.add_source_files(env.modules_sources, "*.cpp")
if env['builtin_pcre2']:
- jit_blacklist = ['javascript']
+ jit_blacklist = ['javascript', 'uwp']
thirdparty_dir = '#thirdparty/pcre2/src/'
thirdparty_flags = ['-DPCRE2_STATIC', '-DHAVE_CONFIG_H']
if 'platform' in env and env['platform'] not in jit_blacklist:
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 48145495e4..765fe4c2f2 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -974,11 +974,6 @@ bool VisualScript::is_tool() const {
return false;
}
-String VisualScript::get_node_type() const {
-
- return String();
-}
-
ScriptLanguage *VisualScript::get_language() const {
return VisualScriptLanguage::singleton;
@@ -2412,6 +2407,10 @@ bool VisualScriptLanguage::has_named_classes() const {
return false;
}
+bool VisualScriptLanguage::supports_builtin_mode() const {
+
+ return true;
+}
int VisualScriptLanguage::find_function(const String &p_function, const String &p_code) const {
return -1;
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 4ae50ee829..0f60b103c9 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -339,8 +339,6 @@ public:
virtual bool is_tool() const;
- virtual String get_node_type() const;
-
virtual ScriptLanguage *get_language() const;
virtual bool has_script_signal(const StringName &p_signal) const;
@@ -569,6 +567,7 @@ public:
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
+ virtual bool supports_builtin_mode() const;
virtual int find_function(const String &p_function, const String &p_code) const;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 972be5f5a4..7c9d306831 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -65,6 +65,8 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"decimals",
"stepify",
"lerp",
+ "inverse_lerp",
+ "range_lerp",
"dectime",
"randomize",
"randi",
@@ -76,6 +78,8 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"rad2deg",
"linear2db",
"db2linear",
+ "wrapi",
+ "wrapf",
"max",
"min",
"clamp",
@@ -194,9 +198,14 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case COLORN:
return 2;
case MATH_LERP:
+ case MATH_INVERSE_LERP:
case MATH_DECTIME:
+ case MATH_WRAP:
+ case MATH_WRAPF:
case LOGIC_CLAMP:
return 3;
+ case MATH_RANGE_LERP:
+ return 5;
case FUNC_MAX: {
}
}
@@ -297,7 +306,26 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::REAL, "to");
else
return PropertyInfo(Variant::REAL, "weight");
-
+ } break;
+ case MATH_INVERSE_LERP: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "from");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "to");
+ else
+ return PropertyInfo(Variant::REAL, "value");
+ } break;
+ case MATH_RANGE_LERP: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "value");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "istart");
+ else if (p_idx == 2)
+ return PropertyInfo(Variant::REAL, "istop");
+ else if (p_idx == 3)
+ return PropertyInfo(Variant::REAL, "ostart");
+ else
+ return PropertyInfo(Variant::REAL, "ostop");
} break;
case MATH_DECTIME: {
if (p_idx == 0)
@@ -340,6 +368,22 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_DB2LINEAR: {
return PropertyInfo(Variant::REAL, "db");
} break;
+ case MATH_WRAP: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::INT, "value");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::INT, "min");
+ else
+ return PropertyInfo(Variant::INT, "max");
+ } break;
+ case MATH_WRAPF: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "value");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "min");
+ else
+ return PropertyInfo(Variant::REAL, "max");
+ } break;
case LOGIC_MAX: {
if (p_idx == 0)
return PropertyInfo(Variant::REAL, "a");
@@ -495,6 +539,8 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case MATH_STEPIFY:
case MATH_LERP:
+ case MATH_INVERSE_LERP:
+ case MATH_RANGE_LERP:
case MATH_DECTIME: {
t = Variant::REAL;
@@ -523,9 +569,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_DEG2RAD:
case MATH_RAD2DEG:
case MATH_LINEAR2DB:
+ case MATH_WRAPF:
case MATH_DB2LINEAR: {
t = Variant::REAL;
} break;
+ case MATH_WRAP: {
+ t = Variant::INT;
+ } break;
case LOGIC_MAX:
case LOGIC_MIN:
case LOGIC_CLAMP: {
@@ -795,6 +845,22 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
+ case VisualScriptBuiltinFunc::MATH_INVERSE_LERP: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANGE_LERP: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ VALIDATE_ARG_NUM(3);
+ VALIDATE_ARG_NUM(4);
+ *r_return = Math::range_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]);
+ } break;
case VisualScriptBuiltinFunc::MATH_DECTIME: {
VALIDATE_ARG_NUM(0);
@@ -856,6 +922,18 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(0);
*r_return = Math::db2linear((double)*p_inputs[0]);
} break;
+ case VisualScriptBuiltinFunc::MATH_WRAP: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::wrapi((int64_t)*p_inputs[0], (int64_t)*p_inputs[1], (int64_t)*p_inputs[2]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_WRAPF: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
case VisualScriptBuiltinFunc::LOGIC_MAX: {
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
@@ -1203,6 +1281,8 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_DECIMALS);
BIND_ENUM_CONSTANT(MATH_STEPIFY);
BIND_ENUM_CONSTANT(MATH_LERP);
+ BIND_ENUM_CONSTANT(MATH_INVERSE_LERP);
+ BIND_ENUM_CONSTANT(MATH_RANGE_LERP);
BIND_ENUM_CONSTANT(MATH_DECTIME);
BIND_ENUM_CONSTANT(MATH_RANDOMIZE);
BIND_ENUM_CONSTANT(MATH_RAND);
@@ -1214,6 +1294,8 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_RAD2DEG);
BIND_ENUM_CONSTANT(MATH_LINEAR2DB);
BIND_ENUM_CONSTANT(MATH_DB2LINEAR);
+ BIND_ENUM_CONSTANT(MATH_WRAP);
+ BIND_ENUM_CONSTANT(MATH_WRAPF);
BIND_ENUM_CONSTANT(LOGIC_MAX);
BIND_ENUM_CONSTANT(LOGIC_MIN);
BIND_ENUM_CONSTANT(LOGIC_CLAMP);
@@ -1236,6 +1318,11 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_MAX);
}
+VisualScriptBuiltinFunc::VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func) {
+
+ this->func = func;
+}
+
VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() {
func = MATH_SIN;
@@ -1244,9 +1331,7 @@ VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() {
template <VisualScriptBuiltinFunc::BuiltinFunc func>
static Ref<VisualScriptNode> create_builtin_func_node(const String &p_name) {
- Ref<VisualScriptBuiltinFunc> node;
- node.instance();
- node->set_func(func);
+ Ref<VisualScriptBuiltinFunc> node = memnew(VisualScriptBuiltinFunc(func));
return node;
}
@@ -1282,6 +1367,8 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECIMALS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/range_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANGE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/dectime", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECTIME>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/rand", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAND>);
@@ -1294,6 +1381,8 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/rad2deg", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAD2DEG>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/linear2db", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LINEAR2DB>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/db2linear", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DB2LINEAR>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAPF>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/max", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MAX>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/min", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MIN>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index 97ab307039..34a2825938 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -64,6 +64,8 @@ public:
MATH_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
+ MATH_INVERSE_LERP,
+ MATH_RANGE_LERP,
MATH_DECTIME,
MATH_RANDOMIZE,
MATH_RAND,
@@ -75,6 +77,8 @@ public:
MATH_RAD2DEG,
MATH_LINEAR2DB,
MATH_DB2LINEAR,
+ MATH_WRAP,
+ MATH_WRAPF,
LOGIC_MAX,
LOGIC_MIN,
LOGIC_CLAMP,
@@ -130,6 +134,7 @@ public:
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);
+ VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func);
VisualScriptBuiltinFunc();
};
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 47ef0182dc..15e20effc0 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -809,7 +809,7 @@ void VisualScriptEditor::_update_members() {
ti->set_text(0, E->get());
Variant var = script->get_variable_default_value(E->get());
- ti->set_suffix(0, "=" + String(var));
+ ti->set_suffix(0, "= " + String(var));
ti->set_icon(0, type_icons[script->get_variable_info(E->get()).type]);
ti->set_selectable(0, true);
@@ -2764,6 +2764,23 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_global_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y));
default_value_edit->set_size(Size2(1, 1));
+
+ if (pinfo.type == Variant::NODE_PATH) {
+
+ Node *edited_scene = get_tree()->get_edited_scene_root();
+ Node *script_node = _find_script_node(edited_scene, edited_scene, script);
+
+ if (script_node) {
+ //pick a node relative to the script, IF the script exists
+ pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE;
+ pinfo.hint_string = script_node->get_path();
+ } else {
+ //pick a path relative to edited scene
+ pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE;
+ pinfo.hint_string = get_tree()->get_edited_scene_root()->get_path();
+ }
+ }
+
if (default_value_edit->edit(NULL, pinfo.name, pinfo.type, existing, pinfo.hint, pinfo.hint_string)) {
if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT)
default_value_edit->popup_centered_ratio();
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 897e910f20..07dca4b904 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -564,6 +564,9 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} else if (id == "PI") {
r_token.type = TK_CONSTANT;
r_token.value = Math_PI;
+ } else if (id == "TAU") {
+ r_token.type = TK_CONSTANT;
+ r_token.value = Math_TAU;
} else if (id == "INF") {
r_token.type = TK_CONSTANT;
r_token.value = Math_INF;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 8d73de9889..a5dc6ffc13 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -858,6 +858,8 @@ public:
if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
if (returns >= 2) {
*p_outputs[1] = v.call(function, p_inputs + 1, input_args, r_error);
+ } else if (returns == 1) {
+ v.call(function, p_inputs + 1, input_args, r_error);
} else {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE";
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 5a34fc3cd9..3863fa7e1c 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -532,6 +532,7 @@ String VisualScriptOperator::get_text() const {
L"A or B", //OP_OR,
L"A xor B", //OP_XOR,
L"not A", //OP_NOT,
+ L"A in B", //OP_IN,
};
return op_names[op];
@@ -1775,8 +1776,8 @@ VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() {
const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = {
"One",
"PI",
- "PIx2",
"PI/2",
+ "TAU",
"E",
"Sqrt2",
"INF",
@@ -1786,8 +1787,8 @@ const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = {
double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX] = {
1.0,
Math_PI,
- Math_PI * 2,
Math_PI * 0.5,
+ Math_TAU,
2.71828182845904523536,
Math::sqrt(2.0),
Math_INF,
@@ -1885,8 +1886,8 @@ void VisualScriptMathConstant::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_CONSTANT_ONE);
BIND_ENUM_CONSTANT(MATH_CONSTANT_PI);
- BIND_ENUM_CONSTANT(MATH_CONSTANT_2PI);
BIND_ENUM_CONSTANT(MATH_CONSTANT_HALF_PI);
+ BIND_ENUM_CONSTANT(MATH_CONSTANT_TAU);
BIND_ENUM_CONSTANT(MATH_CONSTANT_E);
BIND_ENUM_CONSTANT(MATH_CONSTANT_SQRT2);
BIND_ENUM_CONSTANT(MATH_CONSTANT_INF);
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index 421409b265..6648f57e7b 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -474,8 +474,8 @@ public:
enum MathConstant {
MATH_CONSTANT_ONE,
MATH_CONSTANT_PI,
- MATH_CONSTANT_2PI,
MATH_CONSTANT_HALF_PI,
+ MATH_CONSTANT_TAU,
MATH_CONSTANT_E,
MATH_CONSTANT_SQRT2,
MATH_CONSTANT_INF,
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index bc033418ba..3c9076246d 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -82,7 +82,7 @@ String VisualScriptYield::get_text() const {
switch (yield_mode) {
case YIELD_RETURN: return ""; break;
case YIELD_FRAME: return "Next Frame"; break;
- case YIELD_PHYSICS_FRAME: return "Next Fixed Frame"; break;
+ case YIELD_PHYSICS_FRAME: return "Next Physics Frame"; break;
case YIELD_WAIT: return rtos(wait_time) + " sec(s)"; break;
}
@@ -186,7 +186,7 @@ void VisualScriptYield::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_wait_time", "sec"), &VisualScriptYield::set_wait_time);
ClassDB::bind_method(D_METHOD("get_wait_time"), &VisualScriptYield::get_wait_time);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,FixedFrame,Time", PROPERTY_USAGE_NOEDITOR), "set_yield_mode", "get_yield_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,Physics Frame,Time", PROPERTY_USAGE_NOEDITOR), "set_yield_mode", "get_yield_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "wait_time"), "set_wait_time", "get_wait_time");
BIND_ENUM_CONSTANT(YIELD_FRAME);
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index e732d2f86a..9fb6fa8197 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -92,7 +92,7 @@ long AudioStreamPlaybackOGGVorbis::_ov_tell_func(void *_f) {
return fa->get_position();
}
-int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_bufer, int p_frames) {
+int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
if (!playing)
return 0;
@@ -107,9 +107,9 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_bufer, int p_frames) {
}
#ifdef BIG_ENDIAN_ENABLED
- long ret = ov_read(&vf, (char *)p_bufer, todo * stream_channels * sizeof(int16_t), 1, 2, 1, &current_section);
+ long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 1, 2, 1, &current_section);
#else
- long ret = ov_read(&vf, (char *)p_bufer, todo * stream_channels * sizeof(int16_t), 0, 2, 1, &current_section);
+ long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 0, 2, 1, &current_section);
#endif
if (ret < 0) {
@@ -160,7 +160,7 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_bufer, int p_frames) {
frames_mixed += ret;
- p_bufer += ret * stream_channels;
+ p_buffer += ret * stream_channels;
p_frames -= ret;
}
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h
index 2ac13702b5..5000d03fd4 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/vorbis/audio_stream_ogg_vorbis.h
@@ -103,7 +103,7 @@ public:
virtual int get_mix_rate() const { return stream_srate; }
virtual int get_minimum_buffer_size() const { return 0; }
- virtual int mix(int16_t *p_bufer, int p_frames);
+ virtual int mix(int16_t *p_buffer, int p_frames);
AudioStreamPlaybackOGGVorbis();
~AudioStreamPlaybackOGGVorbis();