diff options
Diffstat (limited to 'modules')
250 files changed, 23883 insertions, 8595 deletions
diff --git a/modules/SCsub b/modules/SCsub index d1c0cdc05c..c1cf5a6c1a 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -9,7 +9,6 @@ Export('env_modules') env.modules_sources = [ "register_module_types.gen.cpp", ] -# env.add_source_files(env.modules_sources,"*.cpp") Export('env') for x in env.module_list: 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..0a31c2e503 --- /dev/null +++ b/modules/bullet/config.py @@ -0,0 +1,14 @@ +def can_build(platform): + return True + +def configure(env): + pass + +def get_doc_classes(): + return [ + "BulletPhysicsDirectBodyState", + "BulletPhysicsServer", + ] + +def get_doc_path(): + return "doc_classes" 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/doc_classes/BulletPhysicsDirectBodyState.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml new file mode 100644 index 0000000000..831b346942 --- /dev/null +++ b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/bullet/doc_classes/BulletPhysicsServer.xml b/modules/bullet/doc_classes/BulletPhysicsServer.xml new file mode 100644 index 0000000000..4b5c2e6d83 --- /dev/null +++ b/modules/bullet/doc_classes/BulletPhysicsServer.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="BulletPhysicsServer" inherits="PhysicsServer" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> 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/dds/config.py b/modules/dds/config.py index fb920482f5..5f133eba90 100644 --- a/modules/dds/config.py +++ b/modules/dds/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/enet/config.py b/modules/enet/config.py index fb920482f5..8031fbb4b6 100644 --- a/modules/enet/config.py +++ b/modules/enet/config.py @@ -1,7 +1,13 @@ - def can_build(platform): return True - def configure(env): pass + +def get_doc_classes(): + return [ + "NetworkedMultiplayerENet", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml new file mode 100644 index 0000000000..70ef6aef20 --- /dev/null +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="NetworkedMultiplayerENet" inherits="NetworkedMultiplayerPeer" category="Core" version="3.0-alpha"> + <brief_description> + PacketPeer implementation using the ENet library. + </brief_description> + <description> + A connection (or a listening server) that should be passed to [method SceneTree.set_network_peer]. Socket events can be handled by connecting to [SceneTree] signals. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="close_connection"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="create_client"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="ip" type="String"> + </argument> + <argument index="1" name="port" type="int"> + </argument> + <argument index="2" name="in_bandwidth" type="int" default="0"> + </argument> + <argument index="3" name="out_bandwidth" type="int" default="0"> + </argument> + <description> + Create client that connects to a server at address [code]ip[/code] using specified [code]port[/code]. + </description> + </method> + <method name="create_server"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="port" type="int"> + </argument> + <argument index="1" name="max_clients" type="int" default="32"> + </argument> + <argument index="2" name="in_bandwidth" type="int" default="0"> + </argument> + <argument index="3" name="out_bandwidth" type="int" default="0"> + </argument> + <description> + Create server that listens to connections via [code]port[/code]. + </description> + </method> + <method name="get_compression_mode" qualifiers="const"> + <return type="int" enum="NetworkedMultiplayerENet.CompressionMode"> + </return> + <description> + </description> + </method> + <method name="set_bind_ip"> + <return type="void"> + </return> + <argument index="0" name="ip" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_compression_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="NetworkedMultiplayerENet.CompressionMode"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + <constant name="COMPRESS_NONE" value="0"> + </constant> + <constant name="COMPRESS_RANGE_CODER" value="1"> + </constant> + <constant name="COMPRESS_FASTLZ" value="2"> + </constant> + <constant name="COMPRESS_ZLIB" value="3"> + </constant> + <constant name="COMPRESS_ZSTD" value="4"> + </constant> + </constants> +</class> diff --git a/modules/etc/config.py b/modules/etc/config.py index 7dc2cb59c1..395fc1bb02 100644 --- a/modules/etc/config.py +++ b/modules/etc/config.py @@ -1,8 +1,6 @@ - def can_build(platform): return True - def configure(env): # Tools only, disabled for non-tools # TODO: Find a cleaner way to achieve that diff --git a/modules/freetype/config.py b/modules/freetype/config.py index fb920482f5..5f133eba90 100644 --- a/modules/freetype/config.py +++ b/modules/freetype/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index a6ae143947..66b8d5cbdd 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -12,40 +12,94 @@ 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 + ' ' def _build_gdnative_api_struct_header(api): + ext_wrappers = '' + + for name in api['extensions']: + ext_wrappers += ' extern const godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct;' + + ext_init = 'for (int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ' + ext_init += 'switch (_gdnative_wrapper_api_struct->extensions[i]->type) {' + + for name in api['extensions']: + ext_init += 'case GDNATIVE_EXT_' + api['extensions'][name]['type'] + ': ' + ext_init += '_gdnative_wrapper_' + name + '_api_struct = (' + 'godot_gdnative_ext_' + name + '_api_struct *) _gdnative_wrapper_api_struct->extensions[i]; break;' + + ext_init += '}' + out = [ '/* THIS FILE IS GENERATED DO NOT EDIT */', '#ifndef GODOT_GDNATIVE_API_STRUCT_H', '#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)', + '#define GDNATIVE_API_INIT(options) do { extern const godot_gdnative_api_struct *_gdnative_wrapper_api_struct;' + ext_wrappers + ' _gdnative_wrapper_api_struct = options->api_struct; ' + ext_init + ' } while (0)', '', '#ifdef __cplusplus', 'extern "C" {', '#endif', '', - 'typedef struct godot_gdnative_api_struct {', - '\tvoid *next;', - '\tconst char *version;', + 'typedef struct godot_gdnative_api_version {', + '\tunsigned int major;', + '\tunsigned int minor;', + '} godot_gdnative_api_version;', + '', + 'typedef struct godot_gdnative_api_struct godot_gdnative_api_struct;', + '', + 'struct godot_gdnative_api_struct {', + '\tunsigned int type;', + '\tgodot_gdnative_api_version version;', + '\tconst godot_gdnative_api_struct *next;', + '};', + '', + 'enum GDNATIVE_API_TYPES {', + '\tGDNATIVE_' + api['core']['type'] + ',' + ] + + 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['api']: + 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', '}', @@ -61,14 +115,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') @@ -101,18 +180,23 @@ def _build_gdnative_wrapper_code(api): '#include <gdnative/gdnative.h>', '#include <nativescript/godot_nativescript.h>', '#include <pluginscript/godot_pluginscript.h>', + '#include <arvr/godot_arvr.h>', '', '#include <gdnative_api_struct.gen.h>', '', - 'godot_gdnative_api_struct *_gdnative_wrapper_api_struct = 0;', - '', '#ifdef __cplusplus', 'extern "C" {', '#endif', - '' + '', + 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;', ] - for funcdef in api['api']: + for name in api['extensions']: + out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct;') + + out += [''] + + for funcdef in api['core']['api']: args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) @@ -125,6 +209,20 @@ def _build_gdnative_wrapper_code(api): out.append('}') out.append('') + for name in api['extensions']: + for funcdef in api['extensions'][name]['api']: + args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) + out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) + + args = ', '.join(['%s' % n for t, n in funcdef['arguments']]) + + return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t' + return_line += '_gdnative_wrapper_' + name + '_api_struct->' + funcdef['name'] + '(' + args + ');' + + out.append(return_line) + out.append('}') + out.append('') + out += [ '#ifdef __cplusplus', '}', 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 ff8bda162f..02f2ee7424 100644 --- a/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -166,11 +166,11 @@ void ARVRInterfaceGDNative::uninitialize() { interface->uninitialize(data); } -Size2 ARVRInterfaceGDNative::get_recommended_render_targetsize() { +Size2 ARVRInterfaceGDNative::get_render_targetsize() { ERR_FAIL_COND_V(interface == NULL, Size2()); - godot_vector2 result = interface->get_recommended_render_targetsize(data); + godot_vector2 result = interface->get_render_targetsize(data); Vector2 *vec = (Vector2 *)&result; return *vec; @@ -383,4 +383,16 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p } } } + +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 e45b51e070..96f7b580d5 100644 --- a/modules/gdnative/nativearvr/arvr_interface_gdnative.h +++ b/modules/gdnative/arvr/arvr_interface_gdnative.h @@ -68,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/nativearvr/register_types.cpp b/modules/gdnative/arvr/register_types.cpp index c7d7847a21..139750a02d 100644 --- a/modules/gdnative/nativearvr/register_types.cpp +++ b/modules/gdnative/arvr/register_types.cpp @@ -31,9 +31,9 @@ #include "register_types.h" #include "arvr_interface_gdnative.h" -void register_nativearvr_types() { +void register_arvr_types() { ClassDB::register_class<ARVRInterfaceGDNative>(); } -void unregister_nativearvr_types() { +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/config.py b/modules/gdnative/config.py index df3556249d..68148c4d87 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -1,4 +1,3 @@ - def can_build(platform): return True @@ -6,7 +5,13 @@ def configure(env): env.use_ptrcall = True def get_doc_classes(): - return ["GDNative", "GDNativeLibrary", "NativeScript", "ARVRInterfaceGDNative"] + return [ + "ARVRInterfaceGDNative", + "GDNative", + "GDNativeLibrary", + "NativeScript", + "PluginScript", + ] def get_doc_path(): - return "doc_classes" + return "doc_classes" diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml index 308a7d5946..10957a3394 100644 --- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml +++ b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.0.alpha.custom_build"> +<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.0-alpha"> <brief_description> GDNative wrapper for an ARVR interface </brief_description> diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml index 83a1cf06f0..7a36d09aec 100644 --- a/modules/gdnative/doc_classes/GDNative.xml +++ b/modules/gdnative/doc_classes/GDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNative" inherits="Reference" category="Core" version="3.0.alpha.custom_build"> +<class name="GDNative" inherits="Reference" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index 361c89e6b3..e271665fd4 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.0.alpha.custom_build"> +<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> @@ -9,37 +9,51 @@ <demos> </demos> <methods> - <method name="get_active_library_path" qualifiers="const"> + <method name="get_config_file"> + <return type="ConfigFile"> + </return> + <description> + </description> + </method> + <method name="get_current_dependencies" qualifiers="const"> + <return type="PoolStringArray"> + </return> + <description> + </description> + </method> + <method name="get_current_library_path" qualifiers="const"> <return type="String"> </return> <description> </description> </method> - <method name="get_library_path" qualifiers="const"> + <method name="get_symbol_prefix" qualifiers="const"> <return type="String"> </return> - <argument index="0" name="platform" type="String"> - </argument> <description> </description> </method> - <method name="is_singleton_gdnative" qualifiers="const"> + <method name="is_current_library_statically_linked" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="is_singleton" qualifiers="const"> <return type="bool"> </return> <description> </description> </method> - <method name="set_library_path"> + <method name="set_load_once"> <return type="void"> </return> - <argument index="0" name="platform" type="String"> - </argument> - <argument index="1" name="path" type="String"> + <argument index="0" name="load_once" type="bool"> </argument> <description> </description> </method> - <method name="set_singleton_gdnative"> + <method name="set_singleton"> <return type="void"> </return> <argument index="0" name="singleton" type="bool"> @@ -47,9 +61,27 @@ <description> </description> </method> + <method name="set_symbol_prefix"> + <return type="void"> + </return> + <argument index="0" name="symbol_prefix" type="String"> + </argument> + <description> + </description> + </method> + <method name="should_load_once" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> </methods> <members> - <member name="singleton_gdnative" type="bool" setter="set_singleton_gdnative" getter="is_singleton_gdnative"> + <member name="load_once" type="bool" setter="set_load_once" getter="should_load_once"> + </member> + <member name="singleton" type="bool" setter="set_singleton" getter="is_singleton"> + </member> + <member name="symbol_prefix" type="String" setter="set_symbol_prefix" getter="get_symbol_prefix"> </member> </members> <constants> diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml index b040cfd966..eb4e13f748 100644 --- a/modules/gdnative/doc_classes/NativeScript.xml +++ b/modules/gdnative/doc_classes/NativeScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NativeScript" inherits="Script" category="Core" version="3.0.alpha.custom_build"> +<class name="NativeScript" inherits="Script" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/PluginScript.xml b/modules/gdnative/doc_classes/PluginScript.xml new file mode 100644 index 0000000000..a5ab422d3c --- /dev/null +++ b/modules/gdnative/doc_classes/PluginScript.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PluginScript" inherits="Script" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdnative/gd_native_library_editor.cpp b/modules/gdnative/gd_native_library_editor.cpp index c37b7f473d..fda5dcdcad 100644 --- a/modules/gdnative/gd_native_library_editor.cpp +++ b/modules/gdnative/gd_native_library_editor.cpp @@ -44,7 +44,7 @@ void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory } Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i)); - if (lib.is_valid() && lib->is_singleton_gdnative()) { + if (lib.is_valid() && lib->is_singleton()) { String path = p_dir->get_file_path(i); TreeItem *ti = libraries->create_item(libraries->get_root()); ti->set_text(0, path.get_file()); diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 3fc04a5498..44d6dffc85 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -37,161 +37,56 @@ #include "scene/main/scene_tree.h" -const String init_symbol = "godot_gdnative_init"; -const String terminate_symbol = "godot_gdnative_terminate"; +const String init_symbol = "gdnative_init"; +const String terminate_symbol = "gdnative_terminate"; +const String default_symbol_prefix = "godot_"; // Defined in gdnative_api_struct.gen.cpp -extern const godot_gdnative_api_struct api_struct; - -String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = { - "X11_32bit", - "X11_64bit", - "Windows_32bit", - "Windows_64bit", - "OSX", - - "Android", - - "iOS_32bit", - "iOS_64bit", - - "WebAssembly", - - "" -}; -String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = { - "so", - "so", - "dll", - "dll", - "dylib", - - "so", - - "dylib", - "dylib", - - "wasm", - - "" -}; - -GDNativeLibrary::Platform GDNativeLibrary::current_platform = -#if defined(X11_ENABLED) - (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT); -#elif defined(WINDOWS_ENABLED) - (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT); -#elif defined(OSX_ENABLED) - OSX; -#elif defined(IPHONE_ENABLED) - (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT); -#elif defined(ANDROID_ENABLED) - ANDROID; -#elif defined(JAVASCRIPT_ENABLED) - WASM; -#else - NUM_PLATFORMS; -#endif - -GDNativeLibrary::GDNativeLibrary() - : library_paths(), singleton_gdnative(false) { -} - -GDNativeLibrary::~GDNativeLibrary() { -} +extern const godot_gdnative_core_api_struct api_struct; -void GDNativeLibrary::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path); - ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path); - ClassDB::bind_method(D_METHOD("get_active_library_path"), &GDNativeLibrary::get_active_library_path); +Map<String, Vector<Ref<GDNative> > > *GDNativeLibrary::loaded_libraries = NULL; - ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative); - ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative); +GDNativeLibrary::GDNativeLibrary() { + config_file.instance(); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative"); -} + symbol_prefix = default_symbol_prefix; -bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) { - String name = p_name; - if (name.begins_with("platform/")) { - set_library_path(name.get_slice("/", 1), p_value); - return true; - } - return false; -} - -bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_ret) const { - String name = p_name; - if (name.begins_with("platform/")) { - r_ret = get_library_path(name.get_slice("/", 1)); - return true; + if (GDNativeLibrary::loaded_libraries == NULL) { + GDNativeLibrary::loaded_libraries = memnew((Map<String, Vector<Ref<GDNative> > >)); } - return false; } -void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < NUM_PLATFORMS; i++) { - p_list->push_back(PropertyInfo(Variant::STRING, - "platform/" + platform_names[i], - PROPERTY_HINT_FILE, - "*." + platform_lib_ext[i])); - } +GDNativeLibrary::~GDNativeLibrary() { } -void GDNativeLibrary::set_library_path(StringName p_platform, String p_path) { - int i; - for (i = 0; i <= NUM_PLATFORMS; i++) { - if (i == NUM_PLATFORMS) break; - if (platform_names[i] == p_platform) { - break; - } - } - - if (i == NUM_PLATFORMS) { - ERR_EXPLAIN(String("No such platform: ") + p_platform); - ERR_FAIL(); - } - - library_paths[i] = p_path; -} +void GDNativeLibrary::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file); -String GDNativeLibrary::get_library_path(StringName p_platform) const { - int i; - for (i = 0; i <= NUM_PLATFORMS; i++) { - if (i == NUM_PLATFORMS) break; - if (platform_names[i] == p_platform) { - break; - } - } + ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path); + ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies); + ClassDB::bind_method(D_METHOD("is_current_library_statically_linked"), &GDNativeLibrary::is_current_library_statically_linked); - if (i == NUM_PLATFORMS) { - ERR_EXPLAIN(String("No such platform: ") + p_platform); - ERR_FAIL_V(""); - } + ClassDB::bind_method(D_METHOD("should_load_once"), &GDNativeLibrary::should_load_once); + ClassDB::bind_method(D_METHOD("is_singleton"), &GDNativeLibrary::is_singleton); + ClassDB::bind_method(D_METHOD("get_symbol_prefix"), &GDNativeLibrary::get_symbol_prefix); - return library_paths[i]; -} + ClassDB::bind_method(D_METHOD("set_load_once", "load_once"), &GDNativeLibrary::set_load_once); + ClassDB::bind_method(D_METHOD("set_singleton", "singleton"), &GDNativeLibrary::set_singleton); + ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix); -String GDNativeLibrary::get_active_library_path() const { - if (GDNativeLibrary::current_platform != NUM_PLATFORMS) { - return library_paths[GDNativeLibrary::current_platform]; - } - return ""; + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton"); + ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix"); } GDNative::GDNative() { native_handle = NULL; + initialized = false; } GDNative::~GDNative() { } -extern "C" void _api_anchor(); - -void GDNative::_compile_dummy_for_api() { - _api_anchor(); -} - void GDNative::_bind_methods() { ClassDB::bind_method(D_METHOD("set_library", "library"), &GDNative::set_library); ClassDB::bind_method(D_METHOD("get_library"), &GDNative::get_library); @@ -220,8 +115,8 @@ bool GDNative::initialize() { return false; } - String lib_path = library->get_active_library_path(); - if (lib_path.empty()) { + String lib_path = library->get_current_library_path(); + if (lib_path.empty() && !library->is_current_library_statically_linked()) { ERR_PRINT("No library set for this platform"); return false; } @@ -230,16 +125,34 @@ bool GDNative::initialize() { #else String path = ProjectSettings::get_singleton()->globalize_path(lib_path); #endif + + if (library->should_load_once()) { + if (GDNativeLibrary::loaded_libraries->has(lib_path)) { + // already loaded. Don't load again. + // copy some of the stuff instead + this->native_handle = (*GDNativeLibrary::loaded_libraries)[lib_path][0]->native_handle; + initialized = true; + return true; + } + } + Error err = OS::get_singleton()->open_dynamic_library(path, native_handle); - if (err != OK) { + if (err != OK && !library->is_current_library_statically_linked()) { return false; } void *library_init; - err = get_symbol(init_symbol, library_init); + + // we cheat here a little bit. you saw nothing + initialized = true; + + err = get_symbol(library->get_symbol_prefix() + init_symbol, library_init); + + initialized = false; if (err || !library_init) { - OS::get_singleton()->close_dynamic_library(native_handle); + if (!library->is_current_library_statically_linked()) + OS::get_singleton()->close_dynamic_library(native_handle); native_handle = NULL; ERR_PRINT("Failed to obtain godot_gdnative_init symbol"); return false; @@ -260,18 +173,42 @@ bool GDNative::initialize() { library_init_fpointer(&options); + initialized = true; + + if (library->should_load_once() && !GDNativeLibrary::loaded_libraries->has(lib_path)) { + Vector<Ref<GDNative> > gdnatives; + gdnatives.resize(1); + gdnatives[0] = Ref<GDNative>(this); + GDNativeLibrary::loaded_libraries->insert(lib_path, gdnatives); + } + return true; } bool GDNative::terminate() { - if (native_handle == NULL) { + if (!initialized) { ERR_PRINT("No valid library handle, can't terminate GDNative object"); return false; } + if (library->should_load_once()) { + Vector<Ref<GDNative> > *gdnatives = &(*GDNativeLibrary::loaded_libraries)[library->get_current_library_path()]; + if (gdnatives->size() > 1) { + // there are other GDNative's still using this library, so we actually don't terminte + gdnatives->erase(Ref<GDNative>(this)); + initialized = false; + return true; + } else if (gdnatives->size() == 1) { + // we're the last one, terminate! + gdnatives->clear(); + // wew this looks scary, but all it does is remove the entry completely + GDNativeLibrary::loaded_libraries->erase(GDNativeLibrary::loaded_libraries->find(library->get_current_library_path())); + } + } + void *library_terminate; - Error error = get_symbol(terminate_symbol, library_terminate); + Error error = get_symbol(library->get_symbol_prefix() + terminate_symbol, library_terminate); if (error || !library_terminate) { OS::get_singleton()->close_dynamic_library(native_handle); native_handle = NULL; @@ -281,13 +218,13 @@ bool GDNative::terminate() { godot_gdnative_terminate_fn library_terminate_pointer; library_terminate_pointer = (godot_gdnative_terminate_fn)library_terminate; - // TODO(karroffel): remove this? Should be part of NativeScript, not - // GDNative IMO godot_gdnative_terminate_options options; options.in_editor = Engine::get_singleton()->is_editor_hint(); library_terminate_pointer(&options); + initialized = false; + // GDNativeScriptLanguage::get_singleton()->initialized_libraries.erase(p_native_lib->path); OS::get_singleton()->close_dynamic_library(native_handle); @@ -297,7 +234,7 @@ bool GDNative::terminate() { } bool GDNative::is_initialized() { - return (native_handle != NULL); + return initialized; } void GDNativeCallRegistry::register_native_call_type(StringName p_call_type, native_call_cb p_callback) { @@ -342,7 +279,7 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) { - if (native_handle == NULL) { + if (!initialized) { ERR_PRINT("No valid library handle, can't get symbol from GDNative object"); return ERR_CANT_OPEN; } @@ -355,3 +292,159 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) { return result; } + +RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error) { + Ref<GDNativeLibrary> lib; + lib.instance(); + + Ref<ConfigFile> config = lib->get_config_file(); + + Error err = config->load(p_path); + + if (r_error) { + *r_error = err; + } + + lib->set_singleton(config->get_value("general", "singleton", false)); + lib->set_load_once(config->get_value("general", "load_once", true)); + lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix)); + + String entry_lib_path; + { + + List<String> entry_keys; + config->get_section_keys("entry", &entry_keys); + + for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + entry_lib_path = config->get_value("entry", key); + break; + } + } + + Vector<String> dependency_paths; + { + + List<String> dependency_keys; + config->get_section_keys("dependencies", &dependency_keys); + + for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + dependency_paths = config->get_value("dependencies", key); + break; + } + } + + bool is_statically_linked = false; + { + + List<String> static_linking_keys; + config->get_section_keys("static_linking", &static_linking_keys); + + for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + is_statically_linked = config->get_value("static_linking", key); + break; + } + } + + lib->current_library_path = entry_lib_path; + lib->current_dependencies = dependency_paths; + lib->current_library_statically_linked = is_statically_linked; + + return lib; +} + +void GDNativeLibraryResourceLoader::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("gdnlib"); +} + +bool GDNativeLibraryResourceLoader::handles_type(const String &p_type) const { + return p_type == "GDNativeLibrary"; +} + +String GDNativeLibraryResourceLoader::get_resource_type(const String &p_path) const { + String el = p_path.get_extension().to_lower(); + if (el == "gdnlib") + return "GDNativeLibrary"; + return ""; +} + +Error GDNativeLibraryResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { + + Ref<GDNativeLibrary> lib = p_resource; + + if (lib.is_null()) { + return ERR_INVALID_DATA; + } + + Ref<ConfigFile> config = lib->get_config_file(); + + config->set_value("general", "singleton", lib->is_singleton()); + config->set_value("general", "load_once", lib->should_load_once()); + config->set_value("general", "symbol_prefix", lib->get_symbol_prefix()); + + return config->save(p_path); +} + +bool GDNativeLibraryResourceSaver::recognize(const RES &p_resource) const { + return Object::cast_to<GDNativeLibrary>(*p_resource) != NULL; +} + +void GDNativeLibraryResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { + if (Object::cast_to<GDNativeLibrary>(*p_resource) != NULL) { + p_extensions->push_back("gdnlib"); + } +} diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index e44cc55a79..061dff9267 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -38,66 +38,69 @@ #include "gdnative/gdnative.h" #include "gdnative_api_struct.gen.h" -class GDNativeLibrary : public Resource { - GDCLASS(GDNativeLibrary, Resource) - - enum Platform { - X11_32BIT, - X11_64BIT, - WINDOWS_32BIT, - WINDOWS_64BIT, - // NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only - OSX, - - // Android .so files must be located in directories corresponding to Android ABI names: - // https://developer.android.com/ndk/guides/abis.html - // Android runtime will select the matching library depending on the device. - // The value here must simply point to the .so name, for example: - // "res://libmy_gdnative.so" or "libmy_gdnative.so", - // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so", - // "lib/android/arm64-v8a/libmy_gdnative.so". - ANDROID, - - IOS_32BIT, - IOS_64BIT, - - // TODO(karroffel): figure out how to deal with web stuff at all... - WASM, - - // TODO(karroffel): does UWP have different libs?? - // UWP, +#include "io/config_file.h" - NUM_PLATFORMS +class GDNativeLibraryResourceLoader; +class GDNative; - }; +class GDNativeLibrary : public Resource { + GDCLASS(GDNativeLibrary, Resource) - static String platform_names[NUM_PLATFORMS + 1]; - static String platform_lib_ext[NUM_PLATFORMS + 1]; + static Map<String, Vector<Ref<GDNative> > > *loaded_libraries; - static Platform current_platform; + friend class GDNativeLibraryResourceLoader; + friend class GDNative; - String library_paths[NUM_PLATFORMS]; + Ref<ConfigFile> config_file; - bool singleton_gdnative; + String current_library_path; + Vector<String> current_dependencies; + bool current_library_statically_linked; -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + bool singleton; + bool load_once; + String symbol_prefix; public: GDNativeLibrary(); ~GDNativeLibrary(); - static void _bind_methods(); + _FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; } + + // things that change per-platform + // so there are no setters for this + _FORCE_INLINE_ String get_current_library_path() const { + return current_library_path; + } + _FORCE_INLINE_ Vector<String> get_current_dependencies() const { + return current_dependencies; + } + _FORCE_INLINE_ bool is_current_library_statically_linked() const { + return current_library_statically_linked; + } - void set_library_path(StringName p_platform, String p_path); - String get_library_path(StringName p_platform) const; + // things that are a property of the library itself, not platform specific + _FORCE_INLINE_ bool should_load_once() const { + return load_once; + } + _FORCE_INLINE_ bool is_singleton() const { + return singleton; + } + _FORCE_INLINE_ String get_symbol_prefix() const { + return symbol_prefix; + } - String get_active_library_path() const; + _FORCE_INLINE_ void set_load_once(bool p_load_once) { + load_once = p_load_once; + } + _FORCE_INLINE_ void set_singleton(bool p_singleton) { + singleton = p_singleton; + } + _FORCE_INLINE_ void set_symbol_prefix(String p_symbol_prefix) { + symbol_prefix = p_symbol_prefix; + } - _FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; } - _FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; } + static void _bind_methods(); }; typedef godot_variant (*native_call_cb)(void *, godot_array *); @@ -124,10 +127,9 @@ class GDNative : public Reference { Ref<GDNativeLibrary> library; - // TODO(karroffel): different platforms? WASM???? void *native_handle; - void _compile_dummy_for_api(); + bool initialized; public: GDNative(); @@ -148,4 +150,19 @@ public: Error get_symbol(StringName p_procedure_name, void *&r_handle); }; +class GDNativeLibraryResourceLoader : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error); + 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 GDNativeLibraryResourceSaver : public ResourceFormatSaver { +public: + virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags); + virtual bool recognize(const RES &p_resource) const; + virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; +}; + #endif // GDNATIVE_H diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 51c023981f..e0d9514985 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -41,9 +41,6 @@ extern "C" { #endif -void _array_api_anchor() { -} - void GDAPI godot_array_new(godot_array *r_dest) { Array *dest = (Array *)r_dest; memnew_placement(dest, Array); @@ -158,6 +155,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..39ca754dc7 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _basis_api_anchor() {} - 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) { const Vector3 *x_axis = (const Vector3 *)p_x_axis; const Vector3 *y_axis = (const Vector3 *)p_y_axis; @@ -172,7 +170,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/color.cpp b/modules/gdnative/gdnative/color.cpp index 2a5c0887a1..281a4c416f 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _color_api_anchor() {} - 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) { Color *dest = (Color *)r_dest; diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index ed98cdbb00..8363416946 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -38,8 +38,6 @@ extern "C" { #endif -void _dictionary_api_anchor() {} - void GDAPI godot_dictionary_new(godot_dictionary *r_dest) { Dictionary *dest = (Dictionary *)r_dest; memnew_placement(dest, Dictionary); @@ -130,6 +128,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/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 64a7c33cf8..6dfa7ec20b 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -30,57 +30,16 @@ #include "gdnative/gdnative.h" #include "class_db.h" +#include "engine.h" #include "error_macros.h" #include "global_constants.h" #include "os/os.h" -#include "project_settings.h" #include "variant.h" #ifdef __cplusplus extern "C" { #endif -extern "C" void _string_api_anchor(); -extern "C" void _string_name_api_anchor(); -extern "C" void _vector2_api_anchor(); -extern "C" void _rect2_api_anchor(); -extern "C" void _vector3_api_anchor(); -extern "C" void _transform2d_api_anchor(); -extern "C" void _plane_api_anchor(); -extern "C" void _quat_api_anchor(); -extern "C" void _basis_api_anchor(); -extern "C" void _rect3_api_anchor(); -extern "C" void _transform_api_anchor(); -extern "C" void _color_api_anchor(); -extern "C" void _node_path_api_anchor(); -extern "C" void _rid_api_anchor(); -extern "C" void _dictionary_api_anchor(); -extern "C" void _array_api_anchor(); -extern "C" void _pool_arrays_api_anchor(); -extern "C" void _variant_api_anchor(); - -void _api_anchor() { - - _string_api_anchor(); - _string_name_api_anchor(); - _vector2_api_anchor(); - _rect2_api_anchor(); - _vector3_api_anchor(); - _transform2d_api_anchor(); - _plane_api_anchor(); - _quat_api_anchor(); - _rect3_api_anchor(); - _basis_api_anchor(); - _transform_api_anchor(); - _color_api_anchor(); - _node_path_api_anchor(); - _rid_api_anchor(); - _dictionary_api_anchor(); - _array_api_anchor(); - _pool_arrays_api_anchor(); - _variant_api_anchor(); -} - void GDAPI godot_object_destroy(godot_object *p_o) { memdelete((Object *)p_o); } @@ -88,7 +47,7 @@ void GDAPI godot_object_destroy(godot_object *p_o) { // Singleton API godot_object GDAPI *godot_global_get_singleton(char *p_name) { - return (godot_object *)ProjectSettings::get_singleton()->get_singleton_object(String(p_name)); + return (godot_object *)Engine::get_singleton()->get_singleton_object(String(p_name)); } // result shouldn't be freed void GDAPI *godot_get_stack_bottom() { @@ -133,14 +92,6 @@ godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, god return ret; } -// @Todo -/* -void GDAPI godot_method_bind_varcall(godot_method_bind *p_method_bind) -{ - -} -*/ - godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classname) { ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname)); if (class_info) diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 50fade5b94..2bd278e050 100644 --- a/modules/gdnative/gdnative/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _node_path_api_anchor() {} - void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from) { NodePath *dest = (NodePath *)r_dest; const String *from = (const String *)p_from; diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp index a5e05ffa6b..c92efb8d99 100644 --- a/modules/gdnative/gdnative/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _plane_api_anchor() {} - 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) { Plane *dest = (Plane *)r_dest; diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 1393374da2..562cc344a9 100644 --- a/modules/gdnative/gdnative/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -41,9 +41,6 @@ extern "C" { #endif -void _pool_arrays_api_anchor() { -} - #define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) // byte @@ -106,6 +103,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 +192,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 +277,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 +373,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 +470,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 +566,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 +662,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 +695,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/quat.cpp b/modules/gdnative/gdnative/quat.cpp index 7db7847da1..2d012c069f 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _quat_api_anchor() {} - 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) { Quat *dest = (Quat *)r_dest; diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index ecd8cce9ca..b0b0e28138 100644 --- a/modules/gdnative/gdnative/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _rect2_api_anchor() {} - void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size) { const Vector2 *position = (const Vector2 *)p_pos; const Vector2 *size = (const Vector2 *)p_size; diff --git a/modules/gdnative/gdnative/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp index d34d964db9..8e088743b4 100644 --- a/modules/gdnative/gdnative/rect3.cpp +++ b/modules/gdnative/gdnative/rect3.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _rect3_api_anchor() {} - void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) { const Vector3 *pos = (const Vector3 *)p_pos; const Vector3 *size = (const Vector3 *)p_size; diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp index f05c39906c..c6e8d82494 100644 --- a/modules/gdnative/gdnative/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -37,8 +37,6 @@ extern "C" { #endif -void _rid_api_anchor() {} - void GDAPI godot_rid_new(godot_rid *r_dest) { RID *dest = (RID *)r_dest; memnew_placement(dest, RID); diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 905c513d9d..781b8754bd 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -39,9 +39,6 @@ extern "C" { #endif -void _string_api_anchor() { -} - void GDAPI godot_string_new(godot_string *r_dest) { String *dest = (String *)r_dest; memnew_placement(dest, String); @@ -65,11 +62,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 +84,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/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index 5c00fdfc2f..5c79e0acbd 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -38,9 +38,6 @@ extern "C" { #endif -void _string_name_api_anchor() { -} - void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name) { StringName *dest = (StringName *)r_dest; const String *name = (const String *)p_name; diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index d7a3e78d3f..96b2ec8a7a 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _transform_api_anchor() {} - 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) { const Vector3 *x_axis = (const Vector3 *)p_x_axis; const Vector3 *y_axis = (const Vector3 *)p_y_axis; diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index dcb54f7a53..0a6334516b 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _transform2d_api_anchor() {} - void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos) { const Vector2 *pos = (const Vector2 *)p_pos; Transform2D *dest = (Transform2D *)r_dest; diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 9ba4166c1d..0c31bc643c 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _variant_api_anchor() {} - #define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) // Constructors diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 67f858997f..7a5b29e0c4 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _vector2_api_anchor() {} - void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) { Vector2 *dest = (Vector2 *)r_dest; diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index c85a3f1c08..11ffb3320b 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -36,8 +36,6 @@ extern "C" { #endif -void _vector3_api_anchor() {} - void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) { Vector3 *dest = (Vector3 *)r_dest; diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 31b021b751..770fb429c7 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1,5313 +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_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"] + "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 1a8970d396..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 */ @@ -47,7 +47,7 @@ typedef struct { godot_bool (*is_initialized)(const void *); godot_bool (*initialize)(void *); void (*uninitialize)(void *); - godot_vector2 (*get_recommended_render_targetsize)(const 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 *); @@ -70,6 +70,7 @@ 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 } diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h index d0639589b7..01ae61e280 100644 --- a/modules/gdnative/include/gdnative/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -76,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 b86b1c17d8..49ca765a01 100644 --- a/modules/gdnative/include/gdnative/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -97,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/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index e68d0fdc29..6d1f436921 100644 --- a/modules/gdnative/include/gdnative/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -85,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 25d45db306..a479eced16 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -53,7 +53,7 @@ extern "C" { // This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!! #ifdef _WIN32 -#define GDN_EXPORT __declspec(dllexport) +#define GDN_EXPORT #else #define GDN_EXPORT #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; diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h index 93181f2a6b..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 *) @@ -149,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); @@ -176,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); @@ -203,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); @@ -230,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); @@ -257,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); @@ -284,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); @@ -311,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); @@ -318,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/string.h b/modules/gdnative/include/gdnative/string.h index f30fdb8dc7..29510313c9 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -66,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/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 63fb71feb6..f9d699fb59 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -32,9 +32,9 @@ #ifdef TOOLS_ENABLED #include "core/class_db.h" +#include "core/engine.h" #include "core/global_constants.h" #include "core/pair.h" -#include "core/project_settings.h" #include "os/file_access.h" // helper stuff @@ -177,7 +177,7 @@ List<ClassAPI> generate_c_api_classes() { if (name.begins_with("_")) { name.remove(0); } - class_api.is_singleton = ProjectSettings::get_singleton()->has_singleton(name); + class_api.is_singleton = Engine::get_singleton()->has_singleton(name); } class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name); diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index c1df7def2e..c2c7c27f25 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -40,6 +40,8 @@ #include "scene/main/scene_tree.h" #include "scene/resources/scene_format_text.h" +#include <stdlib.h> + #ifndef NO_THREADS #include "os/thread.h" #endif @@ -52,7 +54,11 @@ #include "editor/editor_node.h" #endif -////// Script stuff +// +// +// Script stuff +// +// void NativeScript::_bind_methods() { ClassDB::bind_method(D_METHOD("set_class_name", "class_name"), &NativeScript::set_class_name); @@ -108,7 +114,7 @@ void NativeScript::set_library(Ref<GDNativeLibrary> p_library) { return; } library = p_library; - lib_path = library->get_active_library_path(); + lib_path = library->get_current_library_path(); #ifndef NO_THREADS if (Thread::get_caller_id() != Thread::get_main_id()) { @@ -414,7 +420,6 @@ Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::Call } } -// TODO(karroffel): implement this NativeScript::NativeScript() { library = Ref<GDNative>(); lib_path = ""; @@ -424,7 +429,6 @@ NativeScript::NativeScript() { #endif } -// TODO(karroffel): implement this NativeScript::~NativeScript() { NSL->unregister_script(this); @@ -433,7 +437,11 @@ NativeScript::~NativeScript() { #endif } -////// ScriptInstance stuff +// +// +// ScriptInstance stuff +// +// #define GET_SCRIPT_DESC() script->get_script_desc() @@ -691,7 +699,6 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringNam return RPC_MODE_DISABLED; } -// TODO(karroffel): implement this NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { NativeScriptDesc *script_data = GET_SCRIPT_DESC(); @@ -774,15 +781,14 @@ NativeScriptInstance::~NativeScriptInstance() { } } -////// ScriptingLanguage stuff +// +// +// ScriptingLanguage stuff +// +// NativeScriptLanguage *NativeScriptLanguage::singleton; -extern "C" void _native_script_hook(); -void NativeScriptLanguage::_hacky_api_anchor() { - _native_script_hook(); -} - void NativeScriptLanguage::_unload_stuff() { for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) { for (Map<StringName, NativeScriptDesc>::Element *C = L->get().front(); C; C = C->next()) { @@ -819,9 +825,7 @@ NativeScriptLanguage::NativeScriptLanguage() { #endif } -// TODO(karroffel): implement this NativeScriptLanguage::~NativeScriptLanguage() { - // _unload_stuff(); // NOTE(karroffel): This gets called in ::finish() for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { @@ -847,7 +851,6 @@ void _add_reload_node() { #endif } -// TODO(karroffel): implement this void NativeScriptLanguage::init() { #if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) @@ -860,6 +863,7 @@ void NativeScriptLanguage::init() { if (generate_c_api(E->next()->get()) != OK) { ERR_PRINT("Failed to generate C API\n"); } + exit(0); } #endif @@ -886,11 +890,9 @@ void NativeScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) co void NativeScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { } -// TODO(karroffel): implement this Ref<Script> NativeScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { NativeScript *s = memnew(NativeScript); s->set_class_name(p_class_name); - // TODO(karroffel): use p_base_class_name return Ref<NativeScript>(s); } bool NativeScriptLanguage::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 { @@ -988,7 +990,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { MutexLock lock(mutex); #endif // See if this library was "registered" already. - const String &lib_path = lib->get_active_library_path(); + const String &lib_path = lib->get_current_library_path(); ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform"); ERR_FAIL_COND(lib_path.length() == 0); Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); @@ -998,7 +1000,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { gdn.instance(); gdn->set_library(lib); - // TODO(karroffel): check the return value? + // TODO check the return value? gdn->initialize(); library_gdnatives.insert(lib_path, gdn); @@ -1010,7 +1012,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { void *proc_ptr; - Error err = gdn->get_symbol(_init_call_name, proc_ptr); + Error err = gdn->get_symbol(lib->get_symbol_prefix() + _init_call_name, proc_ptr); if (err != OK) { ERR_PRINT(String("No " + _init_call_name + " in \"" + lib_path + "\" found").utf8().get_data()); @@ -1051,7 +1053,7 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) { if (L->get()->is_initialized()) { void *proc_ptr; - Error err = L->get()->get_symbol(name, proc_ptr); + Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + name, proc_ptr); if (!err) { ((void (*)())proc_ptr)(); @@ -1140,7 +1142,7 @@ void NativeReloadNode::_notification(int p_what) { // here the library registers all the classes and stuff. void *proc_ptr; - Error err = L->get()->get_symbol("godot_nativescript_init", proc_ptr); + Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + "nativescript_init", proc_ptr); if (err != OK) { ERR_PRINT(String("No godot_nativescript_init in \"" + L->key() + "\" found").utf8().get_data()); } else { diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index e8fc9e6880..f0f14e2f30 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -229,15 +229,15 @@ public: Map<String, Set<NativeScript *> > library_script_users; const StringName _init_call_type = "nativescript_init"; - const StringName _init_call_name = "godot_nativescript_init"; + const StringName _init_call_name = "nativescript_init"; const StringName _noarg_call_type = "nativescript_no_arg"; - const StringName _frame_call_name = "godot_nativescript_frame"; + const StringName _frame_call_name = "nativescript_frame"; #ifndef NO_THREADS - const StringName _thread_enter_call_name = "godot_nativescript_thread_enter"; - const StringName _thread_exit_call_name = "godot_nativescript_thread_exit"; + const StringName _thread_enter_call_name = "nativescript_thread_enter"; + const StringName _thread_exit_call_name = "nativescript_thread_exit"; #endif NativeScriptLanguage(); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 87f9cddaa2..29b0a6719c 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -35,7 +35,7 @@ #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" @@ -48,7 +48,7 @@ #include "gd_native_library_editor.h" // Class used to discover singleton gdnative files -void actual_discoverer_handler(); +static void actual_discoverer_handler(); class GDNativeSingletonDiscover : public Object { // GDCLASS(GDNativeSingletonDiscover, Object) @@ -66,7 +66,7 @@ class GDNativeSingletonDiscover : public Object { } }; -Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { +static Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { Set<String> file_paths; @@ -81,7 +81,7 @@ Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { } Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i)); - if (lib.is_valid() && lib->is_singleton_gdnative()) { + if (lib.is_valid() && lib->is_singleton()) { file_paths.insert(p_dir->get_file_path(i)); } } @@ -98,7 +98,7 @@ Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { return file_paths; } -void actual_discoverer_handler() { +static void actual_discoverer_handler() { EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->get_filesystem(); Set<String> file_paths = get_gdnative_singletons(dir); @@ -115,7 +115,125 @@ void actual_discoverer_handler() { ProjectSettings::get_singleton()->save(); } -GDNativeSingletonDiscover *discoverer = NULL; +static GDNativeSingletonDiscover *discoverer = NULL; + +class GDNativeExportPlugin : public EditorExportPlugin { + +protected: + virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features); +}; + +void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { + if (p_type != "GDNativeLibrary") { + return; + } + + Ref<GDNativeLibrary> lib = ResourceLoader::load(p_path); + + if (lib.is_null()) { + return; + } + + Ref<ConfigFile> config = lib->get_config_file(); + + String entry_lib_path; + { + + List<String> entry_keys; + config->get_section_keys("entry", &entry_keys); + + for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = p_features.has(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + entry_lib_path = config->get_value("entry", key); + break; + } + } + + Vector<String> dependency_paths; + { + + List<String> dependency_keys; + config->get_section_keys("dependencies", &dependency_keys); + + for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = p_features.has(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + dependency_paths = config->get_value("dependencies", key); + break; + } + } + + bool is_statically_linked = false; + { + + List<String> static_linking_keys; + config->get_section_keys("static_linking", &static_linking_keys); + + for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + + for (int i = 0; i < tags.size(); i++) { + bool has_feature = p_features.has(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + is_statically_linked = config->get_value("static_linking", key); + break; + } + } + + if (!is_statically_linked) + add_shared_object(entry_lib_path); + + for (int i = 0; i < dependency_paths.size(); i++) { + add_shared_object(dependency_paths[i]); + } +} static void editor_init_callback() { @@ -125,11 +243,16 @@ static void editor_init_callback() { discoverer = memnew(GDNativeSingletonDiscover); EditorFileSystem::get_singleton()->connect("filesystem_changed", discoverer, "get_class"); + + Ref<GDNativeExportPlugin> export_plugin; + export_plugin.instance(); + + EditorExport::get_singleton()->add_export_plugin(export_plugin); } #endif -godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *p_args) { +static godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *p_args) { godot_gdnative_procedure_fn proc; proc = (godot_gdnative_procedure_fn)p_procedure_handle; @@ -141,6 +264,9 @@ GDNativeCallRegistry *GDNativeCallRegistry::singleton; Vector<Ref<GDNative> > singleton_gdnatives; +GDNativeLibraryResourceLoader *resource_loader_gdnlib = NULL; +GDNativeLibraryResourceSaver *resource_saver_gdnlib = NULL; + void register_gdnative_types() { #ifdef TOOLS_ENABLED @@ -153,11 +279,17 @@ void register_gdnative_types() { ClassDB::register_class<GDNativeLibrary>(); ClassDB::register_class<GDNative>(); + resource_loader_gdnlib = memnew(GDNativeLibraryResourceLoader); + resource_saver_gdnlib = memnew(GDNativeLibraryResourceSaver); + + ResourceLoader::add_resource_format_loader(resource_loader_gdnlib); + ResourceSaver::add_resource_format_saver(resource_saver_gdnlib); + GDNativeCallRegistry::singleton = memnew(GDNativeCallRegistry); GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); - register_nativearvr_types(); + register_arvr_types(); register_nativescript_types(); register_pluginscript_types(); @@ -185,11 +317,11 @@ void register_gdnative_types() { void *proc_ptr; Error err = singleton_gdnatives[i]->get_symbol( - "godot_gdnative_singleton", + lib->get_symbol_prefix() + "gdnative_singleton", 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()); + ERR_PRINT((String("No godot_gdnative_singleton in \"" + singleton_gdnatives[i]->get_library()->get_current_library_path()) + "\" found").utf8().get_data()); } else { ((void (*)())proc_ptr)(); } @@ -214,7 +346,7 @@ void unregister_gdnative_types() { unregister_pluginscript_types(); unregister_nativescript_types(); - unregister_nativearvr_types(); + unregister_arvr_types(); memdelete(GDNativeCallRegistry::singleton); @@ -224,6 +356,9 @@ void unregister_gdnative_types() { } #endif + memdelete(resource_loader_gdnlib); + memdelete(resource_saver_gdnlib); + // This is for printing out the sizes of the core types /* diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py index 5698a37295..6496b59d75 100644 --- a/modules/gdscript/config.py +++ b/modules/gdscript/config.py @@ -1,8 +1,15 @@ - - def can_build(platform): return True - def configure(env): pass + +def get_doc_classes(): + return [ + "GDScript", + "GDScriptFunctionState", + "GDScriptNativeClass", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml new file mode 100644 index 0000000000..13d45aa520 --- /dev/null +++ b/modules/gdscript/doc_classes/GDScript.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GDScript" inherits="Script" category="Core" version="3.0-alpha"> + <brief_description> + A script implemented in the GDScript programming language. + </brief_description> + <description> + A script implemented in the GDScript programming language. The script exends the functionality of all objects that instance it. + [method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_as_byte_code" qualifiers="const"> + <return type="PoolByteArray"> + </return> + <description> + Returns byte code for the script source code. + </description> + </method> + <method name="new" qualifiers="vararg"> + <return type="Object"> + </return> + <description> + Returns a new instance of the script. + For example: + [codeblock] + var MyClass = load("myclass.gd") + var instance = MyClass.new() + assert(instance.get_script() == MyClass) + [/codeblock] + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdscript/doc_classes/GDScriptFunctionState.xml b/modules/gdscript/doc_classes/GDScriptFunctionState.xml new file mode 100644 index 0000000000..2df4e7c217 --- /dev/null +++ b/modules/gdscript/doc_classes/GDScriptFunctionState.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GDScriptFunctionState" inherits="Reference" category="Core" version="3.0-alpha"> + <brief_description> + State of a function call after yielding. + </brief_description> + <description> + Calling [method @GDScript.yield] within a function will cause that function to yield and return its current state as an object of this type. The yielded function call can then be resumed later by calling [method resume] on this state object. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="is_valid" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="extended_check" type="bool" default="false"> + </argument> + <description> + Check whether the function call may be resumed. This is not the case if the function state was already resumed. + If [code]extended_check[/code] is enabled, it also checks if the associated script and object still exist. The extended check is done in debug mode as part of [method GDScriptFunctionState.resume], but you can use this if you know you may be trying to resume without knowing for sure the object and/or script have survived up to that point. + </description> + </method> + <method name="resume"> + <return type="Variant"> + </return> + <argument index="0" name="arg" type="Variant" default="null"> + </argument> + <description> + Resume execution of the yielded function call. + If handed an argument, return the argument from the [method @GDScript.yield] call in the yielded function call. You can pass e.g. an [Array] to hand multiple arguments. + This function returns what the resumed function call returns, possibly another function state if yielded again. + </description> + </method> + </methods> + <signals> + <signal name="completed"> + <argument index="0" name="result" type="Nil"> + </argument> + <description> + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml new file mode 100644 index 0000000000..4514a78469 --- /dev/null +++ b/modules/gdscript/doc_classes/GDScriptNativeClass.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GDScriptNativeClass" inherits="Reference" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="new"> + <return type="Variant"> + </return> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gdscript.cpp index 3f3818ffb9..55ea8a5f24 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_script.cpp */ +/* gdscript.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,9 +27,10 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_script.h" +#include "gdscript.h" -#include "gd_compiler.h" +#include "engine.h" +#include "gdscript_compiler.h" #include "global_constants.h" #include "io/file_access_encrypted.h" #include "os/file_access.h" @@ -38,12 +39,12 @@ /////////////////////////// -GDNativeClass::GDNativeClass(const StringName &p_name) { +GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) { name = p_name; } -bool GDNativeClass::_get(const StringName &p_name, Variant &r_ret) const { +bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const { bool ok; int v = ClassDB::get_integer_constant(name, p_name, &ok); @@ -56,12 +57,12 @@ bool GDNativeClass::_get(const StringName &p_name, Variant &r_ret) const { } } -void GDNativeClass::_bind_methods() { +void GDScriptNativeClass::_bind_methods() { - ClassDB::bind_method(D_METHOD("new"), &GDNativeClass::_new); + ClassDB::bind_method(D_METHOD("new"), &GDScriptNativeClass::_new); } -Variant GDNativeClass::_new() { +Variant GDScriptNativeClass::_new() { Object *o = instance(); if (!o) { @@ -77,16 +78,16 @@ Variant GDNativeClass::_new() { } } -Object *GDNativeClass::instance() { +Object *GDScriptNativeClass::instance() { return ClassDB::instance(name); } -GDInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) { +GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) { /* STEP 1, CREATE */ - GDInstance *instance = memnew(GDInstance); + GDScriptInstance *instance = memnew(GDScriptInstance); instance->base_ref = p_isref; instance->members.resize(member_indices.size()); instance->script = Ref<GDScript>(this); @@ -162,7 +163,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallErro ref = REF(r); } - GDInstance *instance = _create_instance(p_args, p_argcount, owner, r != NULL, r_error); + GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != NULL, r_error); if (!instance) { if (ref.is_null()) { memdelete(owner); //no owner, sorry @@ -217,7 +218,7 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { - for (const Map<StringName, GDFunction *>::Element *E = member_functions.front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { MethodInfo mi; mi.name = E->key(); for (int i = 0; i < E->get()->get_argument_count(); i++) { @@ -271,7 +272,7 @@ bool GDScript::has_method(const StringName &p_method) const { MethodInfo GDScript::get_method_info(const StringName &p_method) const { - const Map<StringName, GDFunction *>::Element *E = member_functions.find(p_method); + const Map<StringName, GDScriptFunction *>::Element *E = member_functions.find(p_method); if (!E) return MethodInfo(); @@ -419,15 +420,15 @@ bool GDScript::_update_exports() { if (basedir != "") basedir = basedir.get_base_dir(); - GDParser parser; + GDScriptParser parser; Error err = parser.parse(source, basedir, true, path); if (err == OK) { - const GDParser::Node *root = parser.get_parse_tree(); - ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, false); + const GDScriptParser::Node *root = parser.get_parse_tree(); + ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false); - const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode *>(root); + const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(root); if (base_cache.is_valid()) { base_cache->inheriters_cache.erase(get_instance_id()); @@ -571,7 +572,7 @@ Error GDScript::reload(bool p_keep_state) { } valid = false; - GDParser parser; + GDScriptParser parser; Error err = parser.parse(source, basedir, false, path); if (err) { if (ScriptDebugger::get_singleton()) { @@ -583,7 +584,7 @@ Error GDScript::reload(bool p_keep_state) { bool can_run = ScriptServer::is_scripting_enabled() || parser.is_tool_script(); - GDCompiler compiler; + GDScriptCompiler compiler; err = compiler.compile(&parser, this, p_keep_state); if (err) { @@ -619,7 +620,7 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p GDScript *top = this; while (top) { - Map<StringName, GDFunction *>::Element *E = top->member_functions.find(p_method); + Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method); if (E) { if (!E->get()->is_static()) { @@ -698,7 +699,7 @@ void GDScript::_bind_methods() { Vector<uint8_t> GDScript::get_as_byte_code() const { - GDTokenizerBuffer tokenizer; + GDScriptTokenizerBuffer tokenizer; return tokenizer.parse_code_string(source); }; @@ -738,14 +739,14 @@ Error GDScript::load_byte_code(const String &p_path) { basedir = basedir.get_base_dir(); valid = false; - GDParser parser; + GDScriptParser parser; Error err = parser.parse_bytecode(bytecode, basedir, get_path()); if (err) { _err_print_error("GDScript::load_byte_code", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_error_line(), ("Parse Error: " + parser.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT); ERR_FAIL_V(ERR_PARSE_ERROR); } - GDCompiler compiler; + GDScriptCompiler compiler; err = compiler.compile(&parser, this); if (err) { @@ -798,7 +799,7 @@ Error GDScript::load_source_code(const String &p_path) { return OK; } -const Map<StringName, GDFunction *> &GDScript::debug_get_member_functions() const { +const Map<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions() const { return member_functions; } @@ -885,7 +886,7 @@ GDScript::GDScript() } GDScript::~GDScript() { - for (Map<StringName, GDFunction *>::Element *E = member_functions.front(); E; E = E->next()) { + for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { memdelete(E->get()); } @@ -909,7 +910,7 @@ GDScript::~GDScript() { // INSTANCE // ////////////////////////////// -bool GDInstance::set(const StringName &p_name, const Variant &p_value) { +bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { //member { @@ -931,7 +932,7 @@ bool GDInstance::set(const StringName &p_name, const Variant &p_value) { GDScript *sptr = script.ptr(); while (sptr) { - Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._set); + Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._set); if (E) { Variant name = p_name; @@ -948,7 +949,7 @@ bool GDInstance::set(const StringName &p_name, const Variant &p_value) { return false; } -bool GDInstance::get(const StringName &p_name, Variant &r_ret) const { +bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { const GDScript *sptr = script.ptr(); while (sptr) { @@ -958,7 +959,7 @@ bool GDInstance::get(const StringName &p_name, Variant &r_ret) const { if (E) { if (E->get().getter) { Variant::CallError err; - r_ret = const_cast<GDInstance *>(this)->call(E->get().getter, NULL, 0, err); + r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, NULL, 0, err); if (err.error == Variant::CallError::CALL_OK) { return true; } @@ -982,14 +983,14 @@ bool GDInstance::get(const StringName &p_name, Variant &r_ret) const { } { - const Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get); + const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get); if (E) { Variant name = p_name; const Variant *args[1] = { &name }; Variant::CallError err; - Variant ret = const_cast<GDFunction *>(E->get())->call(const_cast<GDInstance *>(this), (const Variant **)args, 1, err); + Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err); if (err.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) { r_ret = ret; return true; @@ -1002,7 +1003,7 @@ bool GDInstance::get(const StringName &p_name, Variant &r_ret) const { return false; } -Variant::Type GDInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { +Variant::Type GDScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { const GDScript *sptr = script.ptr(); while (sptr) { @@ -1020,7 +1021,7 @@ Variant::Type GDInstance::get_property_type(const StringName &p_name, bool *r_is return Variant::NIL; } -void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const { +void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { // exported members, not doen yet! const GDScript *sptr = script.ptr(); @@ -1028,11 +1029,11 @@ void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const { while (sptr) { - const Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list); + const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list); if (E) { Variant::CallError err; - Variant ret = const_cast<GDFunction *>(E->get())->call(const_cast<GDInstance *>(this), NULL, 0, err); + Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err); if (err.error == Variant::CallError::CALL_OK) { if (ret.get_type() != Variant::ARRAY) { @@ -1091,12 +1092,12 @@ void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const { } } -void GDInstance::get_method_list(List<MethodInfo> *p_list) const { +void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const { const GDScript *sptr = script.ptr(); while (sptr) { - for (Map<StringName, GDFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) { + for (Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) { MethodInfo mi; mi.name = E->key(); @@ -1109,11 +1110,11 @@ void GDInstance::get_method_list(List<MethodInfo> *p_list) const { } } -bool GDInstance::has_method(const StringName &p_method) const { +bool GDScriptInstance::has_method(const StringName &p_method) const { const GDScript *sptr = script.ptr(); while (sptr) { - const Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(p_method); + const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); if (E) return true; sptr = sptr->_base; @@ -1121,13 +1122,13 @@ bool GDInstance::has_method(const StringName &p_method) const { return false; } -Variant GDInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { //printf("calling %ls:%i method %ls\n", script->get_path().c_str(), -1, String(p_method).c_str()); GDScript *sptr = script.ptr(); while (sptr) { - Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(p_method); + Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); if (E) { return E->get()->call(this, p_args, p_argcount, r_error); } @@ -1137,13 +1138,13 @@ Variant GDInstance::call(const StringName &p_method, const Variant **p_args, int return Variant(); } -void GDInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { +void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { GDScript *sptr = script.ptr(); Variant::CallError ce; while (sptr) { - Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(p_method); + Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); if (E) { E->get()->call(this, p_args, p_argcount, ce); } @@ -1151,27 +1152,27 @@ void GDInstance::call_multilevel(const StringName &p_method, const Variant **p_a } } -void GDInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount) { +void GDScriptInstance::_ml_call_reversed(GDScript *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); + Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); if (E) { E->get()->call(this, p_args, p_argcount, ce); } } -void GDInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) { +void GDScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) { if (script.ptr()) { _ml_call_reversed(script.ptr(), p_method, p_args, p_argcount); } } -void GDInstance::notification(int p_notification) { +void GDScriptInstance::notification(int p_notification) { //notification is not virtual, it gets called at ALL levels just like in C. Variant value = p_notification; @@ -1179,7 +1180,7 @@ void GDInstance::notification(int p_notification) { GDScript *sptr = script.ptr(); while (sptr) { - Map<StringName, GDFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification); + Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification); if (E) { Variant::CallError err; E->get()->call(this, args, 1, err); @@ -1191,22 +1192,22 @@ void GDInstance::notification(int p_notification) { } } -Ref<Script> GDInstance::get_script() const { +Ref<Script> GDScriptInstance::get_script() const { return script; } -ScriptLanguage *GDInstance::get_language() { +ScriptLanguage *GDScriptInstance::get_language() { return GDScriptLanguage::get_singleton(); } -GDInstance::RPCMode GDInstance::get_rpc_mode(const StringName &p_method) const { +GDScriptInstance::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const { const GDScript *cscript = script.ptr(); while (cscript) { - const Map<StringName, GDFunction *>::Element *E = cscript->member_functions.find(p_method); + const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method); if (E) { if (E->get()->get_rpc_mode() != RPC_MODE_DISABLED) { @@ -1219,7 +1220,7 @@ GDInstance::RPCMode GDInstance::get_rpc_mode(const StringName &p_method) const { return RPC_MODE_DISABLED; } -GDInstance::RPCMode GDInstance::get_rset_mode(const StringName &p_variable) const { +GDScriptInstance::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const { const GDScript *cscript = script.ptr(); @@ -1237,7 +1238,7 @@ GDInstance::RPCMode GDInstance::get_rset_mode(const StringName &p_variable) cons return RPC_MODE_DISABLED; } -void GDInstance::reload_members() { +void GDScriptInstance::reload_members() { #ifdef DEBUG_ENABLED @@ -1268,12 +1269,12 @@ void GDInstance::reload_members() { #endif } -GDInstance::GDInstance() { +GDScriptInstance::GDScriptInstance() { owner = NULL; base_ref = false; } -GDInstance::~GDInstance() { +GDScriptInstance::~GDScriptInstance() { if (script.is_valid() && owner) { #ifndef NO_THREADS GDScriptLanguage::singleton->lock->lock(); @@ -1324,6 +1325,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); @@ -1340,15 +1342,15 @@ void GDScriptLanguage::init() { if (globals.has(n)) continue; - Ref<GDNativeClass> nc = memnew(GDNativeClass(E->get())); + Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get())); _add_global(n, nc); } //populate singletons - List<ProjectSettings::Singleton> singletons; - ProjectSettings::get_singleton()->get_singletons(&singletons); - for (List<ProjectSettings::Singleton>::Element *E = singletons.front(); E; E = E->next()) { + List<Engine::Singleton> singletons; + Engine::get_singleton()->get_singletons(&singletons); + for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { _add_global(E->get().name, E->get().ptr); } @@ -1377,7 +1379,7 @@ void GDScriptLanguage::profiling_start() { lock->lock(); } - SelfList<GDFunction> *elem = function_list.first(); + SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { elem->self()->profile.call_count = 0; elem->self()->profile.self_time = 0; @@ -1422,7 +1424,7 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, lock->lock(); } - SelfList<GDFunction> *elem = function_list.first(); + SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) break; @@ -1452,7 +1454,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ lock->lock(); } - SelfList<GDFunction> *elem = function_list.first(); + SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) break; @@ -1597,17 +1599,18 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so Object *obj = E->get()->placeholders.front()->get()->get_owner(); //save instance info - List<Pair<StringName, Variant> > state; if (obj->get_script_instance()) { + map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >()); + List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()]; obj->get_script_instance()->get_property_state(state); - map[obj->get_instance_id()] = state; obj->set_script(RefPtr()); } else { // no instance found. Let's remove it so we don't loop forever E->get()->placeholders.erase(E->get()->placeholders.front()->get()); } } + #endif for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) { @@ -1665,7 +1668,7 @@ void GDScriptLanguage::frame() { lock->lock(); } - SelfList<GDFunction> *elem = function_list.first(); + SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { elem->self()->profile.last_frame_call_count = elem->self()->profile.frame_call_count; elem->self()->profile.last_frame_self_time = elem->self()->profile.frame_self_time; @@ -1700,6 +1703,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { "bool", "null", "PI", + "TAU", "INF", "NAN", "self", @@ -1749,8 +1753,8 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { w++; } - for (int i = 0; i < GDFunctions::FUNC_MAX; i++) { - p_words->push_back(GDFunctions::get_func_name(GDFunctions::Function(i))); + for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { + p_words->push_back(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))); } } diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gdscript.h index e0d142014a..3f6f431938 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gdscript.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_script.h */ +/* gdscript.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,16 +27,17 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_SCRIPT_H -#define GD_SCRIPT_H +#ifndef GDSCRIPT_H +#define GDSCRIPT_H -#include "gd_function.h" +#include "gdscript_function.h" #include "io/resource_loader.h" #include "io/resource_saver.h" #include "script_language.h" -class GDNativeClass : public Reference { - GDCLASS(GDNativeClass, Reference); +class GDScriptNativeClass : public Reference { + + GDCLASS(GDScriptNativeClass, Reference); StringName name; @@ -48,7 +49,7 @@ public: _FORCE_INLINE_ const StringName &get_name() const { return name; } Variant _new(); Object *instance(); - GDNativeClass(const StringName &p_name); + GDScriptNativeClass(const StringName &p_name); }; class GDScript : public Script { @@ -64,21 +65,21 @@ class GDScript : public Script { ScriptInstance::RPCMode rpc_mode; }; - friend class GDInstance; - friend class GDFunction; - friend class GDCompiler; - friend class GDFunctions; + friend class GDScriptInstance; + friend class GDScriptFunction; + friend class GDScriptCompiler; + friend class GDScriptFunctions; friend class GDScriptLanguage; Variant _static_ref; //used for static call - Ref<GDNativeClass> native; + Ref<GDScriptNativeClass> native; Ref<GDScript> base; GDScript *_base; //fast pointer access GDScript *_owner; //for subclasses Set<StringName> members; //members are just indices to the instanced script. Map<StringName, Variant> constants; - Map<StringName, GDFunction *> member_functions; + Map<StringName, GDScriptFunction *> member_functions; Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script. Map<StringName, Ref<GDScript> > subclasses; Map<StringName, Vector<StringName> > _signals; @@ -99,7 +100,7 @@ class GDScript : public Script { #endif Map<StringName, PropertyInfo> member_info; - GDFunction *initializer; //direct pointer to _init , faster to locate + GDScriptFunction *initializer; //direct pointer to _init , faster to locate int subclass_count; Set<Object *> instances; @@ -109,7 +110,7 @@ class GDScript : public Script { String name; SelfList<GDScript> script_list; - GDInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error); + GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error); void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path); @@ -143,8 +144,8 @@ public: const Map<StringName, Ref<GDScript> > &get_subclasses() const { return subclasses; } const Map<StringName, Variant> &get_constants() const { return constants; } const Set<StringName> &get_members() const { return members; } - const Map<StringName, GDFunction *> &get_member_functions() const { return member_functions; } - const Ref<GDNativeClass> &get_native() const { return native; } + const Map<StringName, GDScriptFunction *> &get_member_functions() const { return member_functions; } + const Ref<GDScriptNativeClass> &get_native() const { return native; } virtual bool has_script_signal(const StringName &p_signal) const; virtual void get_script_signal_list(List<MethodInfo> *r_signals) const; @@ -153,7 +154,7 @@ public: Ref<GDScript> get_base() const; const Map<StringName, MemberInfo> &debug_get_member_indices() const { return member_indices; } - const Map<StringName, GDFunction *> &debug_get_member_functions() const; //this is debug only + const Map<StringName, GDScriptFunction *> &debug_get_member_functions() const; //this is debug only StringName debug_get_member_by_index(int p_idx) const; Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error); @@ -201,11 +202,11 @@ public: ~GDScript(); }; -class GDInstance : public ScriptInstance { +class GDScriptInstance : public ScriptInstance { friend class GDScript; - friend class GDFunction; - friend class GDFunctions; - friend class GDCompiler; + friend class GDScriptFunction; + friend class GDScriptFunctions; + friend class GDScriptCompiler; Object *owner; Ref<GDScript> script; @@ -246,8 +247,8 @@ public: virtual RPCMode get_rpc_mode(const StringName &p_method) const; virtual RPCMode get_rset_mode(const StringName &p_variable) const; - GDInstance(); - ~GDInstance(); + GDScriptInstance(); + ~GDScriptInstance(); }; class GDScriptLanguage : public ScriptLanguage { @@ -261,8 +262,8 @@ class GDScriptLanguage : public ScriptLanguage { struct CallLevel { Variant *stack; - GDFunction *function; - GDInstance *instance; + GDScriptFunction *function; + GDScriptInstance *instance; int *ip; int *line; }; @@ -276,16 +277,16 @@ class GDScriptLanguage : public ScriptLanguage { void _add_global(const StringName &p_name, const Variant &p_value); - friend class GDInstance; + friend class GDScriptInstance; Mutex *lock; friend class GDScript; SelfList<GDScript>::List script_list; - friend class GDFunction; + friend class GDScriptFunction; - SelfList<GDFunction>::List function_list; + SelfList<GDScriptFunction>::List function_list; bool profiling; uint64_t script_frame_time; @@ -295,7 +296,7 @@ public: bool debug_break(const String &p_error, bool p_allow_continue = true); bool debug_break_parse(const String &p_file, int p_line, const String &p_error); - _FORCE_INLINE_ void enter_function(GDInstance *p_instance, GDFunction *p_function, Variant *p_stack, int *p_ip, int *p_line) { + _FORCE_INLINE_ void enter_function(GDScriptInstance *p_instance, GDScriptFunction *p_function, Variant *p_stack, int *p_ip, int *p_line) { if (Thread::get_main_id() != Thread::get_caller_id()) return; //no support for other threads than main for now @@ -446,4 +447,4 @@ public: virtual bool recognize(const RES &p_resource) const; }; -#endif // GD_SCRIPT_H +#endif // GDSCRIPT_H diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 7036a708e5..3121a61436 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_compiler.cpp */ +/* gdscript_compiler.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,10 +27,11 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_compiler.h" -#include "gd_script.h" +#include "gdscript_compiler.h" -bool GDCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) { +#include "gdscript.h" + +bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) { if (!codegen.function_node || codegen.function_node->_static) return false; @@ -38,10 +39,10 @@ bool GDCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p return _is_class_member_property(codegen.script, p_name); } -bool GDCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) { +bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) { GDScript *scr = owner; - GDNativeClass *nc = NULL; + GDScriptNativeClass *nc = NULL; while (scr) { if (scr->native.is_valid()) @@ -54,7 +55,7 @@ bool GDCompiler::_is_class_member_property(GDScript *owner, const StringName &p_ return ClassDB::has_property(nc->get_name(), p_name); } -void GDCompiler::_set_error(const String &p_error, const GDParser::Node *p_node) { +void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) { if (error != "") return; @@ -69,7 +70,7 @@ void GDCompiler::_set_error(const String &p_error, const GDParser::Node *p_node) } } -bool GDCompiler::_create_unary_operator(CodeGen &codegen, const GDParser::OperatorNode *on, Variant::Operator op, int p_stack_level) { +bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level) { ERR_FAIL_COND_V(on->arguments.size() != 1, false); @@ -77,29 +78,29 @@ bool GDCompiler::_create_unary_operator(CodeGen &codegen, const GDParser::Operat if (src_address_a < 0) return false; - codegen.opcodes.push_back(GDFunction::OPCODE_OPERATOR); // perform operator + codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator codegen.opcodes.push_back(src_address_a); // argument 1 codegen.opcodes.push_back(src_address_a); // argument 2 (repeated) - //codegen.opcodes.push_back(GDFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter) + //codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter) return true; } -bool GDCompiler::_create_binary_operator(CodeGen &codegen, const GDParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer) { +bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer) { ERR_FAIL_COND_V(on->arguments.size() != 2, false); int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer); if (src_address_a < 0) return false; - if (src_address_a & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) + if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) p_stack_level++; //uses stack for return, increase stack int src_address_b = _parse_expression(codegen, on->arguments[1], p_stack_level, false, p_initializer); if (src_address_b < 0) return false; - codegen.opcodes.push_back(GDFunction::OPCODE_OPERATOR); // perform operator + codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator codegen.opcodes.push_back(src_address_a); // argument 1 codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) @@ -107,14 +108,14 @@ bool GDCompiler::_create_binary_operator(CodeGen &codegen, const GDParser::Opera } /* -int GDCompiler::_parse_subexpression(CodeGen& codegen,const GDParser::Node *p_expression) { +int GDScriptCompiler::_parse_subexpression(CodeGen& codegen,const GDScriptParser::Node *p_expression) { int ret = _parse_expression(codegen,p_expression); if (ret<0) return ret; - if (ret&(GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS)) { + if (ret&(GDScriptFunction::ADDR_TYPE_STACK<<GDScriptFunction::ADDR_BITS)) { codegen.stack_level++; codegen.check_max_stack_level(); //stack was used, keep value @@ -124,24 +125,24 @@ int GDCompiler::_parse_subexpression(CodeGen& codegen,const GDParser::Node *p_ex } */ -int GDCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDParser::OperatorNode *p_expression, int p_stack_level) { +int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level) { Variant::Operator var_op = Variant::OP_MAX; switch (p_expression->op) { - case GDParser::OperatorNode::OP_ASSIGN_ADD: var_op = Variant::OP_ADD; break; - case GDParser::OperatorNode::OP_ASSIGN_SUB: var_op = Variant::OP_SUBTRACT; break; - case GDParser::OperatorNode::OP_ASSIGN_MUL: var_op = Variant::OP_MULTIPLY; break; - case GDParser::OperatorNode::OP_ASSIGN_DIV: var_op = Variant::OP_DIVIDE; break; - case GDParser::OperatorNode::OP_ASSIGN_MOD: var_op = Variant::OP_MODULE; break; - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: var_op = Variant::OP_SHIFT_LEFT; break; - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: var_op = Variant::OP_SHIFT_RIGHT; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_AND: var_op = Variant::OP_BIT_AND; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_OR: var_op = Variant::OP_BIT_OR; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_XOR: var_op = Variant::OP_BIT_XOR; break; - case GDParser::OperatorNode::OP_INIT_ASSIGN: - case GDParser::OperatorNode::OP_ASSIGN: { + case GDScriptParser::OperatorNode::OP_ASSIGN_ADD: var_op = Variant::OP_ADD; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_SUB: var_op = Variant::OP_SUBTRACT; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_MUL: var_op = Variant::OP_MULTIPLY; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_DIV: var_op = Variant::OP_DIVIDE; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_MOD: var_op = Variant::OP_MODULE; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: var_op = Variant::OP_SHIFT_LEFT; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: var_op = Variant::OP_SHIFT_RIGHT; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_AND: var_op = Variant::OP_BIT_AND; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_OR: var_op = Variant::OP_BIT_OR; break; + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR: var_op = Variant::OP_BIT_XOR; break; + case GDScriptParser::OperatorNode::OP_INIT_ASSIGN: + case GDScriptParser::OperatorNode::OP_ASSIGN: { //none } break; @@ -151,7 +152,7 @@ int GDCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDParser: } } - bool initializer = p_expression->op == GDParser::OperatorNode::OP_INIT_ASSIGN; + bool initializer = p_expression->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN; if (var_op == Variant::OP_MAX) { @@ -161,32 +162,32 @@ int GDCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDParser: if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer)) return -1; - int dst_addr = (p_stack_level) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode codegen.alloc_stack(p_stack_level); return dst_addr; } -int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer) { +int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer) { switch (p_expression->type) { //should parse variable declaration and adjust stack accordingly... - case GDParser::Node::TYPE_IDENTIFIER: { + case GDScriptParser::Node::TYPE_IDENTIFIER: { //return identifier //wait, identifier could be a local variable or something else... careful here, must reference properly //as stack may be more interesting to work with //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases peformance a lot. - const GDParser::IdentifierNode *in = static_cast<const GDParser::IdentifierNode *>(p_expression); + const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression); StringName identifier = in->name; if (_is_class_member_property(codegen, identifier)) { //get property - codegen.opcodes.push_back(GDFunction::OPCODE_GET_MEMBER); // perform operator + codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_MEMBER); // perform operator codegen.opcodes.push_back(codegen.get_name_map_pos(identifier)); // argument 2 (unary only takes one parameter) - int dst_addr = (p_stack_level) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode codegen.alloc_stack(p_stack_level); return dst_addr; @@ -196,7 +197,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (!p_initializer && codegen.stack_identifiers.has(identifier)) { int pos = codegen.stack_identifiers[identifier]; - return pos | (GDFunction::ADDR_TYPE_STACK_VARIABLE << GDFunction::ADDR_BITS); + return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS); } //TRY MEMBERS! if (!codegen.function_node || !codegen.function_node->_static) { @@ -206,7 +207,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (codegen.script->member_indices.has(identifier)) { int idx = codegen.script->member_indices[identifier].index; - return idx | (GDFunction::ADDR_TYPE_MEMBER << GDFunction::ADDR_BITS); //argument (stack root) + return idx | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); //argument (stack root) } } @@ -216,14 +217,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr while (owner) { GDScript *scr = owner; - GDNativeClass *nc = NULL; + GDScriptNativeClass *nc = NULL; while (scr) { if (scr->constants.has(identifier)) { //int idx=scr->constants[identifier]; int idx = codegen.get_name_map_pos(identifier); - return idx | (GDFunction::ADDR_TYPE_CLASS_CONSTANT << GDFunction::ADDR_BITS); //argument (stack root) + return idx | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root) } if (scr->native.is_valid()) nc = scr->native.ptr(); @@ -249,7 +250,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr idx = codegen.constant_map[key]; } - return idx | (GDFunction::ADDR_TYPE_LOCAL_CONSTANT << GDFunction::ADDR_BITS); //make it a local constant (faster access) + return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //make it a local constant (faster access) } } @@ -261,14 +262,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (codegen.script->subclasses.has(identifier)) { //same with a subclass, make it a local constant. int idx = codegen.get_constant_pos(codegen.script->subclasses[identifier]); - return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<<GDFunction::ADDR_BITS); //make it a local constant (faster access) + return idx|(GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT<<GDScriptFunction::ADDR_BITS); //make it a local constant (faster access) }*/ if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) { int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier]; - return idx | (GDFunction::ADDR_TYPE_GLOBAL << GDFunction::ADDR_BITS); //argument (stack root) + return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root) } //not found, error @@ -278,9 +279,9 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr return -1; } break; - case GDParser::Node::TYPE_CONSTANT: { + case GDScriptParser::Node::TYPE_CONSTANT: { //return constant - const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(p_expression); + const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_expression); int idx; @@ -293,20 +294,20 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr idx = codegen.constant_map[cn->value]; } - return idx | (GDFunction::ADDR_TYPE_LOCAL_CONSTANT << GDFunction::ADDR_BITS); //argument (stack root) + return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root) } break; - case GDParser::Node::TYPE_SELF: { + case GDScriptParser::Node::TYPE_SELF: { //return constant if (codegen.function_node && codegen.function_node->_static) { _set_error("'self' not present in static function!", p_expression); return -1; } - return (GDFunction::ADDR_TYPE_SELF << GDFunction::ADDR_BITS); + return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); } break; - case GDParser::Node::TYPE_ARRAY: { + case GDScriptParser::Node::TYPE_ARRAY: { - const GDParser::ArrayNode *an = static_cast<const GDParser::ArrayNode *>(p_expression); + const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression); Vector<int> values; int slevel = p_stack_level; @@ -316,7 +317,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret = _parse_expression(codegen, an->elements[i], slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -324,20 +325,20 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr values.push_back(ret); } - codegen.opcodes.push_back(GDFunction::OPCODE_CONSTRUCT_ARRAY); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY); codegen.opcodes.push_back(values.size()); for (int i = 0; i < values.size(); i++) codegen.opcodes.push_back(values[i]); - int dst_addr = (p_stack_level) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode codegen.alloc_stack(p_stack_level); return dst_addr; } break; - case GDParser::Node::TYPE_DICTIONARY: { + case GDScriptParser::Node::TYPE_DICTIONARY: { - const GDParser::DictionaryNode *dn = static_cast<const GDParser::DictionaryNode *>(p_expression); + const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression); Vector<int> values; int slevel = p_stack_level; @@ -347,7 +348,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret = _parse_expression(codegen, dn->elements[i].key, slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -357,7 +358,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr ret = _parse_expression(codegen, dn->elements[i].value, slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -365,29 +366,29 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr values.push_back(ret); } - codegen.opcodes.push_back(GDFunction::OPCODE_CONSTRUCT_DICTIONARY); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY); codegen.opcodes.push_back(dn->elements.size()); for (int i = 0; i < values.size(); i++) codegen.opcodes.push_back(values[i]); - int dst_addr = (p_stack_level) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode codegen.alloc_stack(p_stack_level); return dst_addr; } break; - case GDParser::Node::TYPE_OPERATOR: { + case GDScriptParser::Node::TYPE_OPERATOR: { //hell breaks loose - const GDParser::OperatorNode *on = static_cast<const GDParser::OperatorNode *>(p_expression); + const GDScriptParser::OperatorNode *on = static_cast<const GDScriptParser::OperatorNode *>(p_expression); switch (on->op) { //call/constructor operator - case GDParser::OperatorNode::OP_PARENT_CALL: { + case GDScriptParser::OperatorNode::OP_PARENT_CALL: { ERR_FAIL_COND_V(on->arguments.size() < 1, -1); - const GDParser::IdentifierNode *in = (const GDParser::IdentifierNode *)on->arguments[0]; + const GDScriptParser::IdentifierNode *in = (const GDScriptParser::IdentifierNode *)on->arguments[0]; Vector<int> arguments; int slevel = p_stack_level; @@ -396,7 +397,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret = _parse_expression(codegen, on->arguments[i], slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -404,7 +405,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr } //push call bytecode - codegen.opcodes.push_back(GDFunction::OPCODE_CALL_SELF_BASE); // basic type constructor + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_SELF_BASE); // basic type constructor codegen.opcodes.push_back(codegen.get_name_map_pos(in->name)); //instance codegen.opcodes.push_back(arguments.size()); //argument count @@ -413,13 +414,13 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr codegen.opcodes.push_back(arguments[i]); //arguments } break; - case GDParser::OperatorNode::OP_CALL: { + case GDScriptParser::OperatorNode::OP_CALL: { - if (on->arguments[0]->type == GDParser::Node::TYPE_TYPE) { + if (on->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) { //construct a basic type ERR_FAIL_COND_V(on->arguments.size() < 1, -1); - const GDParser::TypeNode *tn = (const GDParser::TypeNode *)on->arguments[0]; + const GDScriptParser::TypeNode *tn = (const GDScriptParser::TypeNode *)on->arguments[0]; int vtype = tn->vtype; Vector<int> arguments; @@ -429,7 +430,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret = _parse_expression(codegen, on->arguments[i], slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -437,14 +438,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr } //push call bytecode - codegen.opcodes.push_back(GDFunction::OPCODE_CONSTRUCT); // basic type constructor + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT); // basic type constructor codegen.opcodes.push_back(vtype); //instance codegen.opcodes.push_back(arguments.size()); //argument count codegen.alloc_call(arguments.size()); for (int i = 0; i < arguments.size(); i++) codegen.opcodes.push_back(arguments[i]); //arguments - } else if (on->arguments[0]->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) { + } else if (on->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) { //built in function ERR_FAIL_COND_V(on->arguments.size() < 1, -1); @@ -457,7 +458,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -465,8 +466,8 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr arguments.push_back(ret); } - codegen.opcodes.push_back(GDFunction::OPCODE_CALL_BUILT_IN); - codegen.opcodes.push_back(static_cast<const GDParser::BuiltInFunctionNode *>(on->arguments[0])->function); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN); + codegen.opcodes.push_back(static_cast<const GDScriptParser::BuiltInFunctionNode *>(on->arguments[0])->function); codegen.opcodes.push_back(on->arguments.size() - 1); codegen.alloc_call(on->arguments.size() - 1); for (int i = 0; i < arguments.size(); i++) @@ -476,9 +477,9 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr //regular function ERR_FAIL_COND_V(on->arguments.size() < 2, -1); - const GDParser::Node *instance = on->arguments[0]; + const GDScriptParser::Node *instance = on->arguments[0]; - if (instance->type == GDParser::Node::TYPE_SELF) { + if (instance->type == GDScriptParser::Node::TYPE_SELF) { //room for optimization } @@ -489,16 +490,16 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret; - if (i == 0 && on->arguments[i]->type == GDParser::Node::TYPE_SELF && codegen.function_node && codegen.function_node->_static) { + if (i == 0 && on->arguments[i]->type == GDScriptParser::Node::TYPE_SELF && codegen.function_node && codegen.function_node->_static) { //static call to self - ret = (GDFunction::ADDR_TYPE_CLASS << GDFunction::ADDR_BITS); + ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS); } else if (i == 1) { - if (on->arguments[i]->type != GDParser::Node::TYPE_IDENTIFIER) { + if (on->arguments[i]->type != GDScriptParser::Node::TYPE_IDENTIFIER) { _set_error("Attempt to call a non-identifier.", on); return -1; } - GDParser::IdentifierNode *id = static_cast<GDParser::IdentifierNode *>(on->arguments[i]); + GDScriptParser::IdentifierNode *id = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[i]); ret = codegen.get_name_map_pos(id->name); } else { @@ -506,7 +507,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr ret = _parse_expression(codegen, on->arguments[i], slevel); if (ret < 0) return ret; - if (ret & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -514,14 +515,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr arguments.push_back(ret); } - codegen.opcodes.push_back(p_root ? GDFunction::OPCODE_CALL : GDFunction::OPCODE_CALL_RETURN); // perform operator + codegen.opcodes.push_back(p_root ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN); // perform operator codegen.opcodes.push_back(on->arguments.size() - 2); codegen.alloc_call(on->arguments.size() - 2); for (int i = 0; i < arguments.size(); i++) codegen.opcodes.push_back(arguments[i]); } } break; - case GDParser::OperatorNode::OP_YIELD: { + case GDScriptParser::OperatorNode::OP_YIELD: { ERR_FAIL_COND_V(on->arguments.size() && on->arguments.size() != 2, -1); @@ -532,7 +533,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int ret = _parse_expression(codegen, on->arguments[i], slevel); if (ret < 0) return ret; - if (ret & (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS)) { + if (ret & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) { slevel++; codegen.alloc_stack(slevel); } @@ -540,22 +541,22 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr } //push call bytecode - codegen.opcodes.push_back(arguments.size() == 0 ? GDFunction::OPCODE_YIELD : GDFunction::OPCODE_YIELD_SIGNAL); // basic type constructor + codegen.opcodes.push_back(arguments.size() == 0 ? GDScriptFunction::OPCODE_YIELD : GDScriptFunction::OPCODE_YIELD_SIGNAL); // basic type constructor for (int i = 0; i < arguments.size(); i++) codegen.opcodes.push_back(arguments[i]); //arguments - codegen.opcodes.push_back(GDFunction::OPCODE_YIELD_RESUME); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_YIELD_RESUME); //next will be where to place the result :) } break; //indexing operator - case GDParser::OperatorNode::OP_INDEX: - case GDParser::OperatorNode::OP_INDEX_NAMED: { + case GDScriptParser::OperatorNode::OP_INDEX: + case GDScriptParser::OperatorNode::OP_INDEX_NAMED: { ERR_FAIL_COND_V(on->arguments.size() != 2, -1); int slevel = p_stack_level; - bool named = (on->op == GDParser::OperatorNode::OP_INDEX_NAMED); + bool named = (on->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED); int from = _parse_expression(codegen, on->arguments[0], slevel); if (from < 0) @@ -563,14 +564,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int index; if (named) { - if (on->arguments[0]->type == GDParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { + if (on->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { - GDParser::IdentifierNode *identifier = static_cast<GDParser::IdentifierNode *>(on->arguments[1]); + GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1]); const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(identifier->name); #ifdef DEBUG_ENABLED if (MI && MI->get().getter == codegen.function_node->name) { - String n = static_cast<GDParser::IdentifierNode *>(on->arguments[1])->name; + String n = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1])->name; _set_error("Must use '" + n + "' instead of 'self." + n + "' in getter.", on); return -1; } @@ -578,23 +579,23 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (MI && MI->get().getter == "") { // Faster than indexing self (as if no self. had been used) - return (MI->get().index) | (GDFunction::ADDR_TYPE_MEMBER << GDFunction::ADDR_BITS); + return (MI->get().index) | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); } } - index = codegen.get_name_map_pos(static_cast<GDParser::IdentifierNode *>(on->arguments[1])->name); + index = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1])->name); } else { - if (on->arguments[1]->type == GDParser::Node::TYPE_CONSTANT && static_cast<const GDParser::ConstantNode *>(on->arguments[1])->value.get_type() == Variant::STRING) { + if (on->arguments[1]->type == GDScriptParser::Node::TYPE_CONSTANT && static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value.get_type() == Variant::STRING) { //also, somehow, named (speed up anyway) - StringName name = static_cast<const GDParser::ConstantNode *>(on->arguments[1])->value; + StringName name = static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value; index = codegen.get_name_map_pos(name); named = true; } else { //regular indexing - if (from & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (from & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -605,19 +606,19 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr } } - codegen.opcodes.push_back(named ? GDFunction::OPCODE_GET_NAMED : GDFunction::OPCODE_GET); // perform operator + codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET); // perform operator codegen.opcodes.push_back(from); // argument 1 codegen.opcodes.push_back(index); // argument 2 (unary only takes one parameter) } break; - case GDParser::OperatorNode::OP_AND: { + case GDScriptParser::OperatorNode::OP_AND: { // AND operator with early out on failure int res = _parse_expression(codegen, on->arguments[0], p_stack_level); if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); int jump_fail_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); @@ -626,31 +627,31 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); int jump_fail_pos2 = codegen.opcodes.size(); codegen.opcodes.push_back(0); codegen.alloc_stack(p_stack_level); //it will be used.. - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_TRUE); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); codegen.opcodes[jump_fail_pos] = codegen.opcodes.size(); codegen.opcodes[jump_fail_pos2] = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_FALSE); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - return p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS; + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; } break; - case GDParser::OperatorNode::OP_OR: { + case GDScriptParser::OperatorNode::OP_OR: { // OR operator with early out on success int res = _parse_expression(codegen, on->arguments[0], p_stack_level); if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF); codegen.opcodes.push_back(res); int jump_success_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); @@ -659,32 +660,32 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF); codegen.opcodes.push_back(res); int jump_success_pos2 = codegen.opcodes.size(); codegen.opcodes.push_back(0); codegen.alloc_stack(p_stack_level); //it will be used.. - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_FALSE); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); codegen.opcodes[jump_success_pos] = codegen.opcodes.size(); codegen.opcodes[jump_success_pos2] = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_TRUE); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - return p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS; + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; } break; // ternary operators - case GDParser::OperatorNode::OP_TERNARY_IF: { + case GDScriptParser::OperatorNode::OP_TERNARY_IF: { // x IF a ELSE y operator with early out on failure int res = _parse_expression(codegen, on->arguments[0], p_stack_level); if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); int jump_fail_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); @@ -694,10 +695,10 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr return res; codegen.alloc_stack(p_stack_level); //it will be used.. - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(res); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); int jump_past_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); @@ -706,116 +707,116 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (res < 0) return res; - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN); - codegen.opcodes.push_back(p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); + codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(res); codegen.opcodes[jump_past_pos] = codegen.opcodes.size(); - return p_stack_level | GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS; + return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; } break; //unary operators - case GDParser::OperatorNode::OP_NEG: { + case GDScriptParser::OperatorNode::OP_NEG: { if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_NOT: { + case GDScriptParser::OperatorNode::OP_NOT: { if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_BIT_INVERT: { + case GDScriptParser::OperatorNode::OP_BIT_INVERT: { if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_PREINC: { + case GDScriptParser::OperatorNode::OP_PREINC: { } break; //? - case GDParser::OperatorNode::OP_PREDEC: { + case GDScriptParser::OperatorNode::OP_PREDEC: { } break; - case GDParser::OperatorNode::OP_INC: { + case GDScriptParser::OperatorNode::OP_INC: { } break; - case GDParser::OperatorNode::OP_DEC: { + case GDScriptParser::OperatorNode::OP_DEC: { } break; //binary operators (in precedence order) - case GDParser::OperatorNode::OP_IN: { + case GDScriptParser::OperatorNode::OP_IN: { if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_EQUAL: { + case GDScriptParser::OperatorNode::OP_EQUAL: { if (!_create_binary_operator(codegen, on, Variant::OP_EQUAL, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_NOT_EQUAL: { + case GDScriptParser::OperatorNode::OP_NOT_EQUAL: { if (!_create_binary_operator(codegen, on, Variant::OP_NOT_EQUAL, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_LESS: { + case GDScriptParser::OperatorNode::OP_LESS: { if (!_create_binary_operator(codegen, on, Variant::OP_LESS, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_LESS_EQUAL: { + case GDScriptParser::OperatorNode::OP_LESS_EQUAL: { if (!_create_binary_operator(codegen, on, Variant::OP_LESS_EQUAL, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_GREATER: { + case GDScriptParser::OperatorNode::OP_GREATER: { if (!_create_binary_operator(codegen, on, Variant::OP_GREATER, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_GREATER_EQUAL: { + case GDScriptParser::OperatorNode::OP_GREATER_EQUAL: { if (!_create_binary_operator(codegen, on, Variant::OP_GREATER_EQUAL, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_ADD: { + case GDScriptParser::OperatorNode::OP_ADD: { if (!_create_binary_operator(codegen, on, Variant::OP_ADD, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_SUB: { + case GDScriptParser::OperatorNode::OP_SUB: { if (!_create_binary_operator(codegen, on, Variant::OP_SUBTRACT, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_MUL: { + case GDScriptParser::OperatorNode::OP_MUL: { if (!_create_binary_operator(codegen, on, Variant::OP_MULTIPLY, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_DIV: { + case GDScriptParser::OperatorNode::OP_DIV: { if (!_create_binary_operator(codegen, on, Variant::OP_DIVIDE, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_MOD: { + case GDScriptParser::OperatorNode::OP_MOD: { if (!_create_binary_operator(codegen, on, Variant::OP_MODULE, p_stack_level)) return -1; } break; - //case GDParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break; - //case GDParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break; - case GDParser::OperatorNode::OP_BIT_AND: { + //case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break; + //case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break; + case GDScriptParser::OperatorNode::OP_BIT_AND: { if (!_create_binary_operator(codegen, on, Variant::OP_BIT_AND, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_BIT_OR: { + case GDScriptParser::OperatorNode::OP_BIT_OR: { if (!_create_binary_operator(codegen, on, Variant::OP_BIT_OR, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_BIT_XOR: { + case GDScriptParser::OperatorNode::OP_BIT_XOR: { if (!_create_binary_operator(codegen, on, Variant::OP_BIT_XOR, p_stack_level)) return -1; } break; //shift - case GDParser::OperatorNode::OP_SHIFT_LEFT: { + case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_LEFT, p_stack_level)) return -1; } break; - case GDParser::OperatorNode::OP_SHIFT_RIGHT: { + case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_RIGHT, p_stack_level)) return -1; } break; //assignment operators - case GDParser::OperatorNode::OP_ASSIGN_ADD: - case GDParser::OperatorNode::OP_ASSIGN_SUB: - case GDParser::OperatorNode::OP_ASSIGN_MUL: - case GDParser::OperatorNode::OP_ASSIGN_DIV: - case GDParser::OperatorNode::OP_ASSIGN_MOD: - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: - case GDParser::OperatorNode::OP_ASSIGN_BIT_AND: - case GDParser::OperatorNode::OP_ASSIGN_BIT_OR: - case GDParser::OperatorNode::OP_ASSIGN_BIT_XOR: - case GDParser::OperatorNode::OP_INIT_ASSIGN: - case GDParser::OperatorNode::OP_ASSIGN: { + case GDScriptParser::OperatorNode::OP_ASSIGN_ADD: + case GDScriptParser::OperatorNode::OP_ASSIGN_SUB: + case GDScriptParser::OperatorNode::OP_ASSIGN_MUL: + case GDScriptParser::OperatorNode::OP_ASSIGN_DIV: + case GDScriptParser::OperatorNode::OP_ASSIGN_MOD: + case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: + case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_AND: + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_OR: + case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR: + case GDScriptParser::OperatorNode::OP_INIT_ASSIGN: + case GDScriptParser::OperatorNode::OP_ASSIGN: { ERR_FAIL_COND_V(on->arguments.size() != 2, -1); - if (on->arguments[0]->type == GDParser::Node::TYPE_OPERATOR && (static_cast<GDParser::OperatorNode *>(on->arguments[0])->op == GDParser::OperatorNode::OP_INDEX || static_cast<GDParser::OperatorNode *>(on->arguments[0])->op == GDParser::OperatorNode::OP_INDEX_NAMED)) { + if (on->arguments[0]->type == GDScriptParser::Node::TYPE_OPERATOR && (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX || static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED)) { //SET (chained) MODE!! #ifdef DEBUG_ENABLED - if (static_cast<GDParser::OperatorNode *>(on->arguments[0])->op == GDParser::OperatorNode::OP_INDEX_NAMED) { - const GDParser::OperatorNode *inon = static_cast<GDParser::OperatorNode *>(on->arguments[0]); + if (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { + const GDScriptParser::OperatorNode *inon = static_cast<GDScriptParser::OperatorNode *>(on->arguments[0]); - if (inon->arguments[0]->type == GDParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { + if (inon->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { - const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(static_cast<GDParser::IdentifierNode *>(inon->arguments[1])->name); + const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name); if (MI && MI->get().setter == codegen.function_node->name) { - String n = static_cast<GDParser::IdentifierNode *>(inon->arguments[1])->name; + String n = static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name; _set_error("Must use '" + n + "' instead of 'self." + n + "' in setter.", inon); return -1; } @@ -825,34 +826,34 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int slevel = p_stack_level; - GDParser::OperatorNode *op = static_cast<GDParser::OperatorNode *>(on->arguments[0]); + GDScriptParser::OperatorNode *op = static_cast<GDScriptParser::OperatorNode *>(on->arguments[0]); /* Find chain of sets */ StringName assign_property; - List<GDParser::OperatorNode *> chain; + List<GDScriptParser::OperatorNode *> chain; { //create get/set chain - GDParser::OperatorNode *n = op; + GDScriptParser::OperatorNode *n = op; while (true) { chain.push_back(n); - if (n->arguments[0]->type != GDParser::Node::TYPE_OPERATOR) { + if (n->arguments[0]->type != GDScriptParser::Node::TYPE_OPERATOR) { //check for a built-in property - if (n->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER) { + if (n->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - GDParser::IdentifierNode *identifier = static_cast<GDParser::IdentifierNode *>(n->arguments[0]); + GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->arguments[0]); if (_is_class_member_property(codegen, identifier->name)) { assign_property = identifier->name; } } break; } - n = static_cast<GDParser::OperatorNode *>(n->arguments[0]); - if (n->op != GDParser::OperatorNode::OP_INDEX && n->op != GDParser::OperatorNode::OP_INDEX_NAMED) + n = static_cast<GDScriptParser::OperatorNode *>(n->arguments[0]); + if (n->op != GDScriptParser::OperatorNode::OP_INDEX && n->op != GDScriptParser::OperatorNode::OP_INDEX_NAMED) break; } } @@ -867,7 +868,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr //print_line("retval: "+itos(retval)); - if (retval & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (retval & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -881,30 +882,30 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr // in Node2D setchain.push_back(prev_pos); setchain.push_back(codegen.get_name_map_pos(assign_property)); - setchain.push_back(GDFunction::OPCODE_SET_MEMBER); + setchain.push_back(GDScriptFunction::OPCODE_SET_MEMBER); } - for (List<GDParser::OperatorNode *>::Element *E = chain.back(); E; E = E->prev()) { + for (List<GDScriptParser::OperatorNode *>::Element *E = chain.back(); E; E = E->prev()) { if (E == chain.front()) //ignore first break; - bool named = E->get()->op == GDParser::OperatorNode::OP_INDEX_NAMED; + bool named = E->get()->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED; int key_idx; if (named) { - key_idx = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode *>(E->get()->arguments[1])->name); + key_idx = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(E->get()->arguments[1])->name); //printf("named key %x\n",key_idx); } else { - if (prev_pos & (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS)) { + if (prev_pos & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) { slevel++; codegen.alloc_stack(slevel); } - GDParser::Node *key = E->get()->arguments[1]; + GDScriptParser::Node *key = E->get()->arguments[1]; key_idx = _parse_expression(codegen, key, slevel); //printf("expr key %x\n",key_idx); @@ -914,12 +915,12 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (key_idx < 0) //error return key_idx; - codegen.opcodes.push_back(named ? GDFunction::OPCODE_GET_NAMED : GDFunction::OPCODE_GET); + codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET); codegen.opcodes.push_back(prev_pos); codegen.opcodes.push_back(key_idx); slevel++; codegen.alloc_stack(slevel); - int dst_pos = (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) | slevel; + int dst_pos = (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | slevel; codegen.opcodes.push_back(dst_pos); @@ -928,7 +929,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr setchain.push_back(dst_pos); setchain.push_back(key_idx); setchain.push_back(prev_pos); - setchain.push_back(named ? GDFunction::OPCODE_SET_NAMED : GDFunction::OPCODE_SET); + setchain.push_back(named ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET); prev_pos = dst_pos; } @@ -938,9 +939,9 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr int set_index; bool named = false; - if (static_cast<const GDParser::OperatorNode *>(op)->op == GDParser::OperatorNode::OP_INDEX_NAMED) { + if (static_cast<const GDScriptParser::OperatorNode *>(op)->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { - set_index = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode *>(op->arguments[1])->name); + set_index = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name); named = true; } else { @@ -951,7 +952,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (set_index < 0) //error return set_index; - if (set_index & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (set_index & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -960,7 +961,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (set_value < 0) //error return set_value; - codegen.opcodes.push_back(named ? GDFunction::OPCODE_SET_NAMED : GDFunction::OPCODE_SET); + codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET); codegen.opcodes.push_back(prev_pos); codegen.opcodes.push_back(set_index); codegen.opcodes.push_back(set_value); @@ -972,7 +973,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr return retval; - } else if (on->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER && _is_class_member_property(codegen, static_cast<GDParser::IdentifierNode *>(on->arguments[0])->name)) { + } else if (on->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER && _is_class_member_property(codegen, static_cast<GDScriptParser::IdentifierNode *>(on->arguments[0])->name)) { //assignment to member property int slevel = p_stack_level; @@ -981,24 +982,24 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (src_address < 0) return -1; - StringName name = static_cast<GDParser::IdentifierNode *>(on->arguments[0])->name; + StringName name = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[0])->name; - codegen.opcodes.push_back(GDFunction::OPCODE_SET_MEMBER); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_SET_MEMBER); codegen.opcodes.push_back(codegen.get_name_map_pos(name)); codegen.opcodes.push_back(src_address); - return GDFunction::ADDR_TYPE_NIL << GDFunction::ADDR_BITS; + return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS; } else { //REGULAR ASSIGNMENT MODE!! int slevel = p_stack_level; - int dst_address_a = _parse_expression(codegen, on->arguments[0], slevel, false, on->op == GDParser::OperatorNode::OP_INIT_ASSIGN); + int dst_address_a = _parse_expression(codegen, on->arguments[0], slevel, false, on->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN); if (dst_address_a < 0) return -1; - if (dst_address_a & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) { + if (dst_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); } @@ -1007,14 +1008,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (src_address_b < 0) return -1; - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN); // perform operator + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator codegen.opcodes.push_back(dst_address_a); // argument 1 codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) return dst_address_a; //if anything, returns wathever was assigned or correct stack position } } break; - case GDParser::OperatorNode::OP_IS: { + case GDScriptParser::OperatorNode::OP_IS: { ERR_FAIL_COND_V(on->arguments.size() != 2, false); @@ -1024,14 +1025,14 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr if (src_address_a < 0) return -1; - if (src_address_a & GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) + if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) slevel++; //uses stack for return, increase stack int src_address_b = _parse_expression(codegen, on->arguments[1], slevel); if (src_address_b < 0) return -1; - codegen.opcodes.push_back(GDFunction::OPCODE_EXTENDS_TEST); // perform operator + codegen.opcodes.push_back(GDScriptFunction::OPCODE_EXTENDS_TEST); // perform operator codegen.opcodes.push_back(src_address_a); // argument 1 codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) @@ -1044,7 +1045,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr } break; } - int dst_addr = (p_stack_level) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode codegen.alloc_stack(p_stack_level); return dst_addr; @@ -1060,7 +1061,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr ERR_FAIL_V(-1); //unreachable code } -Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) { +Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) { codegen.push_stack_identifiers(); int new_identifiers = 0; @@ -1068,28 +1069,28 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl for (int i = 0; i < p_block->statements.size(); i++) { - const GDParser::Node *s = p_block->statements[i]; + const GDScriptParser::Node *s = p_block->statements[i]; switch (s->type) { - case GDParser::Node::TYPE_NEWLINE: { + case GDScriptParser::Node::TYPE_NEWLINE: { #ifdef DEBUG_ENABLED - const GDParser::NewLineNode *nl = static_cast<const GDParser::NewLineNode *>(s); - codegen.opcodes.push_back(GDFunction::OPCODE_LINE); + const GDScriptParser::NewLineNode *nl = static_cast<const GDScriptParser::NewLineNode *>(s); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE); codegen.opcodes.push_back(nl->line); codegen.current_line = nl->line; #endif } break; - case GDParser::Node::TYPE_CONTROL_FLOW: { + case GDScriptParser::Node::TYPE_CONTROL_FLOW: { // try subblocks - const GDParser::ControlFlowNode *cf = static_cast<const GDParser::ControlFlowNode *>(s); + const GDScriptParser::ControlFlowNode *cf = static_cast<const GDScriptParser::ControlFlowNode *>(s); switch (cf->cf_type) { - case GDParser::ControlFlowNode::CF_MATCH: { - GDParser::MatchNode *match = cf->match; + case GDScriptParser::ControlFlowNode::CF_MATCH: { + GDScriptParser::MatchNode *match = cf->match; - GDParser::IdentifierNode *id = memnew(GDParser::IdentifierNode); + GDScriptParser::IdentifierNode *id = memnew(GDScriptParser::IdentifierNode); id->name = "#match_value"; // var #match_value @@ -1098,8 +1099,8 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl codegen.alloc_stack(p_stack_level); new_identifiers++; - GDParser::OperatorNode *op = memnew(GDParser::OperatorNode); - op->op = GDParser::OperatorNode::OP_ASSIGN; + GDScriptParser::OperatorNode *op = memnew(GDScriptParser::OperatorNode); + op->op = GDScriptParser::OperatorNode::OP_ASSIGN; op->arguments.push_back(id); op->arguments.push_back(match->val_to_match); @@ -1109,14 +1110,14 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl } // break address - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); int break_addr = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(0); // break addr for (int j = 0; j < match->compiled_pattern_branches.size(); j++) { - GDParser::MatchNode::CompiledPatternBranch branch = match->compiled_pattern_branches[j]; + GDScriptParser::MatchNode::CompiledPatternBranch branch = match->compiled_pattern_branches[j]; // jump over continue // jump unconditionally @@ -1127,11 +1128,11 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl return ERR_PARSE_ERROR; } - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF); codegen.opcodes.push_back(ret); codegen.opcodes.push_back(codegen.opcodes.size() + 3); int continue_addr = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(0); Error err = _parse_block(codegen, branch.body, p_stack_level, p_break_addr, continue_addr); @@ -1139,7 +1140,7 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl return ERR_PARSE_ERROR; } - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(break_addr); codegen.opcodes[continue_addr + 1] = codegen.opcodes.size(); @@ -1149,10 +1150,10 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl } break; - case GDParser::ControlFlowNode::CF_IF: { + case GDScriptParser::ControlFlowNode::CF_IF: { #ifdef DEBUG_ENABLED - codegen.opcodes.push_back(GDFunction::OPCODE_LINE); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE); codegen.opcodes.push_back(cf->line); codegen.current_line = cf->line; #endif @@ -1160,7 +1161,7 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl if (ret < 0) return ERR_PARSE_ERROR; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(ret); int else_addr = codegen.opcodes.size(); codegen.opcodes.push_back(0); //temporary @@ -1171,7 +1172,7 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl if (cf->body_else) { - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); int end_addr = codegen.opcodes.size(); codegen.opcodes.push_back(0); codegen.opcodes[else_addr] = codegen.opcodes.size(); @@ -1187,42 +1188,42 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl } } break; - case GDParser::ControlFlowNode::CF_FOR: { + case GDScriptParser::ControlFlowNode::CF_FOR: { int slevel = p_stack_level; int iter_stack_pos = slevel; - int iterator_pos = (slevel++) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - int counter_pos = (slevel++) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); - int container_pos = (slevel++) | (GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS); + int iterator_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + int counter_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + int container_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.alloc_stack(slevel); codegen.push_stack_identifiers(); - codegen.add_stack_identifier(static_cast<const GDParser::IdentifierNode *>(cf->arguments[0])->name, iter_stack_pos); + codegen.add_stack_identifier(static_cast<const GDScriptParser::IdentifierNode *>(cf->arguments[0])->name, iter_stack_pos); int ret = _parse_expression(codegen, cf->arguments[1], slevel, false); if (ret < 0) return ERR_COMPILATION_FAILED; //assign container - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); codegen.opcodes.push_back(container_pos); codegen.opcodes.push_back(ret); //begin loop - codegen.opcodes.push_back(GDFunction::OPCODE_ITERATE_BEGIN); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE_BEGIN); codegen.opcodes.push_back(counter_pos); codegen.opcodes.push_back(container_pos); codegen.opcodes.push_back(codegen.opcodes.size() + 4); codegen.opcodes.push_back(iterator_pos); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); //skip code for next + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next codegen.opcodes.push_back(codegen.opcodes.size() + 8); //break loop int break_pos = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); //skip code for next + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next codegen.opcodes.push_back(0); //skip code for next //next loop int continue_pos = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_ITERATE); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE); codegen.opcodes.push_back(counter_pos); codegen.opcodes.push_back(container_pos); codegen.opcodes.push_back(break_pos); @@ -1232,52 +1233,52 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl if (err) return err; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_pos); codegen.opcodes[break_pos + 1] = codegen.opcodes.size(); codegen.pop_stack_identifiers(); } break; - case GDParser::ControlFlowNode::CF_WHILE: { + case GDScriptParser::ControlFlowNode::CF_WHILE: { - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); int break_addr = codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(0); int continue_addr = codegen.opcodes.size(); int ret = _parse_expression(codegen, cf->arguments[0], p_stack_level, false); if (ret < 0) return ERR_PARSE_ERROR; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(ret); codegen.opcodes.push_back(break_addr); Error err = _parse_block(codegen, cf->body, p_stack_level, break_addr, continue_addr); if (err) return err; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_addr); codegen.opcodes[break_addr + 1] = codegen.opcodes.size(); } break; - case GDParser::ControlFlowNode::CF_SWITCH: { + case GDScriptParser::ControlFlowNode::CF_SWITCH: { } break; - case GDParser::ControlFlowNode::CF_BREAK: { + case GDScriptParser::ControlFlowNode::CF_BREAK: { if (p_break_addr < 0) { _set_error("'break'' not within loop", cf); return ERR_COMPILATION_FAILED; } - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(p_break_addr); } break; - case GDParser::ControlFlowNode::CF_CONTINUE: { + case GDScriptParser::ControlFlowNode::CF_CONTINUE: { if (p_continue_addr < 0) { @@ -1285,11 +1286,11 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl return ERR_COMPILATION_FAILED; } - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(p_continue_addr); } break; - case GDParser::ControlFlowNode::CF_RETURN: { + case GDScriptParser::ControlFlowNode::CF_RETURN: { int ret; @@ -1301,38 +1302,38 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl } else { - ret = GDFunction::ADDR_TYPE_NIL << GDFunction::ADDR_BITS; + ret = GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS; } - codegen.opcodes.push_back(GDFunction::OPCODE_RETURN); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_RETURN); codegen.opcodes.push_back(ret); } break; } } break; - case GDParser::Node::TYPE_ASSERT: { + case GDScriptParser::Node::TYPE_ASSERT: { #ifdef DEBUG_ENABLED // try subblocks - const GDParser::AssertNode *as = static_cast<const GDParser::AssertNode *>(s); + const GDScriptParser::AssertNode *as = static_cast<const GDScriptParser::AssertNode *>(s); int ret = _parse_expression(codegen, as->condition, p_stack_level, false); if (ret < 0) return ERR_PARSE_ERROR; - codegen.opcodes.push_back(GDFunction::OPCODE_ASSERT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT); codegen.opcodes.push_back(ret); #endif } break; - case GDParser::Node::TYPE_BREAKPOINT: { + case GDScriptParser::Node::TYPE_BREAKPOINT: { #ifdef DEBUG_ENABLED // try subblocks - codegen.opcodes.push_back(GDFunction::OPCODE_BREAKPOINT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_BREAKPOINT); #endif } break; - case GDParser::Node::TYPE_LOCAL_VAR: { + case GDScriptParser::Node::TYPE_LOCAL_VAR: { - const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(s); + const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(s); if (_is_class_member_property(codegen, lv->name)) { _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv); @@ -1356,7 +1357,7 @@ Error GDCompiler::_parse_block(CodeGen &codegen, const GDParser::BlockNode *p_bl return OK; } -Error GDCompiler::_parse_function(GDScript *p_script, const GDParser::ClassNode *p_class, const GDParser::FunctionNode *p_func, bool p_for_ready) { +Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) { Vector<int> bytecode; CodeGen codegen; @@ -1397,10 +1398,10 @@ Error GDCompiler::_parse_function(GDScript *p_script, const GDParser::ClassNode if (!p_func && p_class->extends_used && p_script->native.is_null()) { //call implicit parent constructor - codegen.opcodes.push_back(GDFunction::OPCODE_CALL_SELF_BASE); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_SELF_BASE); codegen.opcodes.push_back(codegen.get_name_map_pos("_init")); codegen.opcodes.push_back(0); - codegen.opcodes.push_back((GDFunction::ADDR_TYPE_STACK << GDFunction::ADDR_BITS) | 0); + codegen.opcodes.push_back((GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | 0); } Error err = _parse_block(codegen, p_class->initializer, stack_level); if (err) @@ -1426,7 +1427,7 @@ Error GDCompiler::_parse_function(GDScript *p_script, const GDParser::ClassNode if (p_func->default_values.size()) { - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); defarg_addr.push_back(codegen.opcodes.size()); for (int i = 0; i < p_func->default_values.size(); i++) { @@ -1449,15 +1450,15 @@ Error GDCompiler::_parse_function(GDScript *p_script, const GDParser::ClassNode func_name = "_init"; } - codegen.opcodes.push_back(GDFunction::OPCODE_END); + codegen.opcodes.push_back(GDScriptFunction::OPCODE_END); /* if (String(p_func->name)=="") { //initializer func gdfunc = &p_script->initializer; */ //} else { //regular func - p_script->member_functions[func_name] = memnew(GDFunction); - GDFunction *gdfunc = p_script->member_functions[func_name]; + p_script->member_functions[func_name] = memnew(GDScriptFunction); + GDScriptFunction *gdfunc = p_script->member_functions[func_name]; //} if (p_func) { @@ -1579,7 +1580,7 @@ Error GDCompiler::_parse_function(GDScript *p_script, const GDParser::ClassNode return OK; } -Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDParser::ClassNode *p_class, bool p_keep_state) { +Error GDScriptCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { Map<StringName, Ref<GDScript> > old_subclasses; @@ -1587,12 +1588,12 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa old_subclasses = p_script->subclasses; } - p_script->native = Ref<GDNativeClass>(); + p_script->native = Ref<GDScriptNativeClass>(); p_script->base = Ref<GDScript>(); p_script->_base = NULL; p_script->members.clear(); p_script->constants.clear(); - for (Map<StringName, GDFunction *>::Element *E = p_script->member_functions.front(); E; E = E->next()) { + for (Map<StringName, GDScriptFunction *>::Element *E = p_script->member_functions.front(); E; E = E->next()) { memdelete(E->get()); } p_script->member_functions.clear(); @@ -1606,7 +1607,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa p_script->tool = p_class->tool; p_script->name = p_class->name; - Ref<GDNativeClass> native; + Ref<GDScriptNativeClass> native; if (p_class->extends_used) { //do inheritance @@ -1801,14 +1802,14 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa for (int i = 0; i < p_class->constant_expressions.size(); i++) { StringName name = p_class->constant_expressions[i].identifier; - ERR_CONTINUE(p_class->constant_expressions[i].expression->type != GDParser::Node::TYPE_CONSTANT); + ERR_CONTINUE(p_class->constant_expressions[i].expression->type != GDScriptParser::Node::TYPE_CONSTANT); if (_is_class_member_property(p_script, name)) { _set_error("Member '" + name + "' already exists as a class property.", p_class); return ERR_ALREADY_EXISTS; } - GDParser::ConstantNode *constant = static_cast<GDParser::ConstantNode *>(p_class->constant_expressions[i].expression); + GDScriptParser::ConstantNode *constant = static_cast<GDScriptParser::ConstantNode *>(p_class->constant_expressions[i].expression); p_script->constants.insert(name, constant->value); //p_script->constants[constant->value].make_const(); @@ -1917,7 +1918,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa for (int i = 0; i < p_class->variables.size(); i++) { if (p_class->variables[i].setter) { - const Map<StringName, GDFunction *>::Element *E = p_script->get_member_functions().find(p_class->variables[i].setter); + const Map<StringName, GDScriptFunction *>::Element *E = p_script->get_member_functions().find(p_class->variables[i].setter); if (!E) { _set_error("Setter function '" + String(p_class->variables[i].setter) + "' not found in class.", NULL); err_line = p_class->variables[i].line; @@ -1934,7 +1935,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa } } if (p_class->variables[i].getter) { - const Map<StringName, GDFunction *>::Element *E = p_script->get_member_functions().find(p_class->variables[i].getter); + const Map<StringName, GDScriptFunction *>::Element *E = p_script->get_member_functions().find(p_class->variables[i].getter); if (!E) { _set_error("Getter function '" + String(p_class->variables[i].getter) + "' not found in class.", NULL); err_line = p_class->variables[i].line; @@ -1970,7 +1971,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa //re-create as an instance p_script->placeholders.erase(psi); //remove placeholder - GDInstance *instance = memnew(GDInstance); + GDScriptInstance *instance = memnew(GDScriptInstance); instance->base_ref = Object::cast_to<Reference>(E->get()); instance->members.resize(p_script->member_indices.size()); instance->script = Ref<GDScript>(p_script); @@ -1994,7 +1995,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa #endif } else { - GDInstance *gi = static_cast<GDInstance *>(si); + GDScriptInstance *gi = static_cast<GDScriptInstance *>(si); gi->reload_members(); } @@ -2007,18 +2008,18 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa return OK; } -Error GDCompiler::compile(const GDParser *p_parser, GDScript *p_script, bool p_keep_state) { +Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) { err_line = -1; err_column = -1; error = ""; parser = p_parser; - const GDParser::Node *root = parser->get_parse_tree(); - ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, ERR_INVALID_DATA); + const GDScriptParser::Node *root = parser->get_parse_tree(); + ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, ERR_INVALID_DATA); source = p_script->get_path(); - Error err = _parse_class(p_script, NULL, static_cast<const GDParser::ClassNode *>(root), p_keep_state); + Error err = _parse_class(p_script, NULL, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state); if (err) return err; @@ -2026,18 +2027,18 @@ Error GDCompiler::compile(const GDParser *p_parser, GDScript *p_script, bool p_k return OK; } -String GDCompiler::get_error() const { +String GDScriptCompiler::get_error() const { return error; } -int GDCompiler::get_error_line() const { +int GDScriptCompiler::get_error_line() const { return err_line; } -int GDCompiler::get_error_column() const { +int GDScriptCompiler::get_error_column() const { return err_column; } -GDCompiler::GDCompiler() { +GDScriptCompiler::GDScriptCompiler() { } diff --git a/modules/gdscript/gd_compiler.h b/modules/gdscript/gdscript_compiler.h index ac713ae75b..6e0457ba30 100644 --- a/modules/gdscript/gd_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_compiler.h */ +/* gdscript_compiler.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,26 +27,26 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_COMPILER_H -#define GD_COMPILER_H +#ifndef GDSCRIPT_COMPILER_H +#define GDSCRIPT_COMPILER_H -#include "gd_parser.h" -#include "gd_script.h" +#include "gdscript.h" +#include "gdscript_parser.h" -class GDCompiler { +class GDScriptCompiler { - const GDParser *parser; + const GDScriptParser *parser; struct CodeGen { GDScript *script; - const GDParser::ClassNode *class_node; - const GDParser::FunctionNode *function_node; + const GDScriptParser::ClassNode *class_node; + const GDScriptParser::FunctionNode *function_node; bool debug_stack; List<Map<StringName, int> > stack_id_stack; Map<StringName, int> stack_identifiers; - List<GDFunction::StackDebug> stack_debug; + List<GDScriptFunction::StackDebug> stack_debug; List<Map<StringName, int> > block_identifier_stack; Map<StringName, int> block_identifiers; @@ -54,7 +54,7 @@ class GDCompiler { stack_identifiers[p_id] = p_stackpos; if (debug_stack) { block_identifiers[p_id] = p_stackpos; - GDFunction::StackDebug sd; + GDScriptFunction::StackDebug sd; sd.added = true; sd.line = current_line; sd.identifier = p_id; @@ -79,7 +79,7 @@ class GDCompiler { if (debug_stack) { for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) { - GDFunction::StackDebug sd; + GDScriptFunction::StackDebug sd; sd.added = false; sd.identifier = E->key(); sd.line = current_line; @@ -129,29 +129,29 @@ class GDCompiler { bool _is_class_member_property(CodeGen &codegen, const StringName &p_name); bool _is_class_member_property(GDScript *owner, const StringName &p_name); - void _set_error(const String &p_error, const GDParser::Node *p_node); + void _set_error(const String &p_error, const GDScriptParser::Node *p_node); - bool _create_unary_operator(CodeGen &codegen, const GDParser::OperatorNode *on, Variant::Operator op, int p_stack_level); - bool _create_binary_operator(CodeGen &codegen, const GDParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer = false); + bool _create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level); + bool _create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer = false); - int _parse_assign_right_expression(CodeGen &codegen, const GDParser::OperatorNode *p_expression, int p_stack_level); - int _parse_expression(CodeGen &codegen, const GDParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false); - Error _parse_block(CodeGen &codegen, const GDParser::BlockNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1); - Error _parse_function(GDScript *p_script, const GDParser::ClassNode *p_class, const GDParser::FunctionNode *p_func, bool p_for_ready = false); - Error _parse_class(GDScript *p_script, GDScript *p_owner, const GDParser::ClassNode *p_class, bool p_keep_state); + int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level); + int _parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false); + Error _parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1); + Error _parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false); + Error _parse_class(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state); int err_line; int err_column; StringName source; String error; public: - Error compile(const GDParser *p_parser, GDScript *p_script, bool p_keep_state = false); + Error compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state = false); String get_error() const; int get_error_line() const; int get_error_column() const; - GDCompiler(); + GDScriptCompiler(); }; -#endif // COMPILER_H +#endif // GDSCRIPT_COMPILER_H diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gdscript_editor.cpp index d9b10ff3fa..a74b8a8483 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_editor.cpp */ +/* gdscript_editor.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,10 +27,10 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_script.h" +#include "gdscript.h" #include "editor/editor_settings.h" -#include "gd_compiler.h" +#include "gdscript_compiler.h" #include "global_constants.h" #include "os/file_access.h" #include "project_settings.h" @@ -92,7 +92,7 @@ void GDScriptLanguage::make_template(const String &p_class_name, const String &p bool GDScriptLanguage::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 { - GDParser parser; + GDScriptParser parser; Error err = parser.parse(p_script, p_path.get_base_dir(), true, p_path); if (err) { @@ -102,10 +102,10 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int & return false; } else { - const GDParser::Node *root = parser.get_parse_tree(); - ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, false); + const GDScriptParser::Node *root = parser.get_parse_tree(); + ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false); - const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root); + const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root); Map<int, String> funcs; for (int i = 0; i < cl->functions.size(); i++) { @@ -138,16 +138,16 @@ bool GDScriptLanguage::supports_builtin_mode() const { int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const { - GDTokenizerText tokenizer; + GDScriptTokenizerText tokenizer; tokenizer.set_code(p_code); int indent = 0; - while (tokenizer.get_token() != GDTokenizer::TK_EOF && tokenizer.get_token() != GDTokenizer::TK_ERROR) { + while (tokenizer.get_token() != GDScriptTokenizer::TK_EOF && tokenizer.get_token() != GDScriptTokenizer::TK_ERROR) { - if (tokenizer.get_token() == GDTokenizer::TK_NEWLINE) { + if (tokenizer.get_token() == GDScriptTokenizer::TK_NEWLINE) { indent = tokenizer.get_token_line_indent(); } - //print_line("TOKEN: "+String(GDTokenizer::get_token_name(tokenizer.get_token()))); - if (indent == 0 && tokenizer.get_token() == GDTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDTokenizer::TK_IDENTIFIER) { + //print_line("TOKEN: "+String(GDScriptTokenizer::get_token_name(tokenizer.get_token()))); + if (indent == 0 && tokenizer.get_token() == GDScriptTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDScriptTokenizer::TK_IDENTIFIER) { String identifier = tokenizer.get_token_identifier(1); if (identifier == p_function) { @@ -155,7 +155,7 @@ int GDScriptLanguage::find_function(const String &p_function, const String &p_co } } tokenizer.advance(); - //print_line("NEXT: "+String(GDTokenizer::get_token_name(tokenizer.get_token()))); + //print_line("NEXT: "+String(GDScriptTokenizer::get_token_name(tokenizer.get_token()))); } return -1; } @@ -245,7 +245,7 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); int l = _debug_call_stack_pos - p_level - 1; - GDFunction *f = _call_stack[l].function; + GDScriptFunction *f = _call_stack[l].function; List<Pair<StringName, int> > locals; @@ -264,7 +264,7 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> * ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); int l = _debug_call_stack_pos - p_level - 1; - GDInstance *instance = _call_stack[l].instance; + GDScriptInstance *instance = _call_stack[l].instance; if (!instance) return; @@ -298,9 +298,9 @@ void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) con void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { - for (int i = 0; i < GDFunctions::FUNC_MAX; i++) { + for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { - p_functions->push_back(GDFunctions::get_info(GDFunctions::Function(i))); + p_functions->push_back(GDScriptFunctions::get_info(GDScriptFunctions::Function(i))); } //not really "functions", but.. @@ -318,7 +318,7 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal")); mi.default_arguments.push_back(Variant::NIL); mi.default_arguments.push_back(Variant::STRING); - mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDFunctionState"); + mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDScriptFunctionState"); p_functions->push_back(mi); } { @@ -337,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; @@ -360,14 +365,14 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na } s += " "; } - s += "):\n\tpass # replace with function body\n"; + s += "):\n" + _get_indentation() + "pass # replace with function body\n"; return s; } #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) -struct GDCompletionIdentifier { +struct GDScriptCompletionIdentifier { String enumeration; StringName obj_type; @@ -376,17 +381,17 @@ struct GDCompletionIdentifier { Variant value; //im case there is a value, also return it }; -static GDCompletionIdentifier _get_type_from_variant(const Variant &p_variant, bool p_allow_gdnative_class = false) { +static GDScriptCompletionIdentifier _get_type_from_variant(const Variant &p_variant, bool p_allow_gdnative_class = false) { - GDCompletionIdentifier t; + GDScriptCompletionIdentifier t; t.type = p_variant.get_type(); t.value = p_variant; if (p_variant.get_type() == Variant::OBJECT) { Object *obj = p_variant; if (obj) { - if (p_allow_gdnative_class && Object::cast_to<GDNativeClass>(obj)) { - t.obj_type = Object::cast_to<GDNativeClass>(obj)->get_name(); + if (p_allow_gdnative_class && Object::cast_to<GDScriptNativeClass>(obj)) { + t.obj_type = Object::cast_to<GDScriptNativeClass>(obj)->get_name(); t.value = Variant(); } else { @@ -397,9 +402,9 @@ static GDCompletionIdentifier _get_type_from_variant(const Variant &p_variant, b return t; } -static GDCompletionIdentifier _get_type_from_pinfo(const PropertyInfo &p_info) { +static GDScriptCompletionIdentifier _get_type_from_pinfo(const PropertyInfo &p_info) { - GDCompletionIdentifier t; + GDScriptCompletionIdentifier t; t.type = p_info.type; if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { t.obj_type = p_info.hint_string; @@ -407,23 +412,23 @@ static GDCompletionIdentifier _get_type_from_pinfo(const PropertyInfo &p_info) { return t; } -struct GDCompletionContext { +struct GDScriptCompletionContext { - const GDParser::ClassNode *_class; - const GDParser::FunctionNode *function; - const GDParser::BlockNode *block; + const GDScriptParser::ClassNode *_class; + const GDScriptParser::FunctionNode *function; + const GDScriptParser::BlockNode *block; Object *base; String base_path; }; -static Ref<Reference> _get_parent_class(GDCompletionContext &context) { +static Ref<Reference> _get_parent_class(GDScriptCompletionContext &context) { if (context._class->extends_used) { //do inheritance String path = context._class->extends_file; Ref<GDScript> script; - Ref<GDNativeClass> native; + Ref<GDScriptNativeClass> native; if (path != "") { //path (and optionally subclasses) @@ -493,17 +498,17 @@ static Ref<Reference> _get_parent_class(GDCompletionContext &context) { return Ref<Reference>(); } -static GDCompletionIdentifier _get_native_class(GDCompletionContext &context) { +static GDScriptCompletionIdentifier _get_native_class(GDScriptCompletionContext &context) { //eeh... - GDCompletionIdentifier id; + GDScriptCompletionIdentifier id; id.type = Variant::NIL; REF pc = _get_parent_class(context); if (!pc.is_valid()) { return id; } - Ref<GDNativeClass> nc = pc; + Ref<GDScriptNativeClass> nc = pc; Ref<GDScript> s = pc; if (s.is_null() && nc.is_null()) { @@ -524,28 +529,28 @@ static GDCompletionIdentifier _get_native_class(GDCompletionContext &context) { return id; } -static bool _guess_identifier_type(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type, bool p_for_indexing); +static bool _guess_identifier_type(GDScriptCompletionContext &context, int p_line, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type, bool p_for_indexing); -static bool _guess_expression_type(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, GDCompletionIdentifier &r_type, bool p_for_indexing = false) { +static bool _guess_expression_type(GDScriptCompletionContext &context, const GDScriptParser::Node *p_node, int p_line, GDScriptCompletionIdentifier &r_type, bool p_for_indexing = false) { - if (p_node->type == GDParser::Node::TYPE_CONSTANT) { + if (p_node->type == GDScriptParser::Node::TYPE_CONSTANT) { - const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(p_node); + const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_node); r_type = _get_type_from_variant(cn->value); return true; - } else if (p_node->type == GDParser::Node::TYPE_DICTIONARY) { + } else if (p_node->type == GDScriptParser::Node::TYPE_DICTIONARY) { r_type.type = Variant::DICTIONARY; //what the heck, fill it anyway - const GDParser::DictionaryNode *an = static_cast<const GDParser::DictionaryNode *>(p_node); + const GDScriptParser::DictionaryNode *an = static_cast<const GDScriptParser::DictionaryNode *>(p_node); Dictionary d; for (int i = 0; i < an->elements.size(); i++) { - GDCompletionIdentifier k; + GDScriptCompletionIdentifier k; if (_guess_expression_type(context, an->elements[i].key, p_line, k) && k.value.get_type() != Variant::NIL) { - GDCompletionIdentifier v; + GDScriptCompletionIdentifier v; if (_guess_expression_type(context, an->elements[i].value, p_line, v)) { d[k.value] = v.value; } @@ -553,15 +558,15 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: } r_type.value = d; return true; - } else if (p_node->type == GDParser::Node::TYPE_ARRAY) { + } else if (p_node->type == GDScriptParser::Node::TYPE_ARRAY) { r_type.type = Variant::ARRAY; //what the heck, fill it anyway - const GDParser::ArrayNode *an = static_cast<const GDParser::ArrayNode *>(p_node); + const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_node); Array arr; arr.resize(an->elements.size()); for (int i = 0; i < an->elements.size(); i++) { - GDCompletionIdentifier ci; + GDScriptCompletionIdentifier ci; if (_guess_expression_type(context, an->elements[i], p_line, ci)) { arr[i] = ci.value; } @@ -569,44 +574,44 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: r_type.value = arr; return true; - } else if (p_node->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) { + } else if (p_node->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) { - MethodInfo mi = GDFunctions::get_info(static_cast<const GDParser::BuiltInFunctionNode *>(p_node)->function); + MethodInfo mi = GDScriptFunctions::get_info(static_cast<const GDScriptParser::BuiltInFunctionNode *>(p_node)->function); r_type = _get_type_from_pinfo(mi.return_val); return true; - } else if (p_node->type == GDParser::Node::TYPE_IDENTIFIER) { + } else if (p_node->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - return _guess_identifier_type(context, p_line - 1, static_cast<const GDParser::IdentifierNode *>(p_node)->name, r_type, p_for_indexing); - } else if (p_node->type == GDParser::Node::TYPE_SELF) { + return _guess_identifier_type(context, p_line - 1, static_cast<const GDScriptParser::IdentifierNode *>(p_node)->name, r_type, p_for_indexing); + } else if (p_node->type == GDScriptParser::Node::TYPE_SELF) { //eeh... r_type = _get_native_class(context); return r_type.type != Variant::NIL; - } else if (p_node->type == GDParser::Node::TYPE_OPERATOR) { + } else if (p_node->type == GDScriptParser::Node::TYPE_OPERATOR) { - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_node); - if (op->op == GDParser::OperatorNode::OP_CALL) { + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_node); + if (op->op == GDScriptParser::OperatorNode::OP_CALL) { - if (op->arguments[0]->type == GDParser::Node::TYPE_TYPE) { + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) { - const GDParser::TypeNode *tn = static_cast<const GDParser::TypeNode *>(op->arguments[0]); + const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(op->arguments[0]); r_type.type = tn->vtype; return true; - } else if (op->arguments[0]->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) { + } else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) { - const GDParser::BuiltInFunctionNode *bin = static_cast<const GDParser::BuiltInFunctionNode *>(op->arguments[0]); + const GDScriptParser::BuiltInFunctionNode *bin = static_cast<const GDScriptParser::BuiltInFunctionNode *>(op->arguments[0]); return _guess_expression_type(context, bin, p_line, r_type); - } else if (op->arguments.size() > 1 && op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) { + } else if (op->arguments.size() > 1 && op->arguments[1]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - StringName id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1])->name; + StringName id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name; - if (op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER && String(id) == "new") { + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER && String(id) == "new") { //shortcut - StringName identifier = static_cast<const GDParser::IdentifierNode *>(op->arguments[0])->name; + StringName identifier = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0])->name; if (ClassDB::class_exists(identifier)) { r_type.type = Variant::OBJECT; @@ -616,7 +621,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: } } - GDCompletionIdentifier base; + GDScriptCompletionIdentifier base; if (!_guess_expression_type(context, op->arguments[0], p_line, base)) return false; @@ -625,8 +630,8 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: if (id.operator String() == "new" && base.value.get_type() == Variant::OBJECT) { Object *obj = base.value; - if (obj && Object::cast_to<GDNativeClass>(obj)) { - GDNativeClass *gdnc = Object::cast_to<GDNativeClass>(obj); + if (obj && Object::cast_to<GDScriptNativeClass>(obj)) { + GDScriptNativeClass *gdnc = Object::cast_to<GDScriptNativeClass>(obj); r_type.type = Variant::OBJECT; r_type.value = Variant(); r_type.obj_type = gdnc->get_name(); @@ -657,7 +662,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: bool all_valid = true; Vector<Variant> args; for (int i = 2; i < op->arguments.size(); i++) { - GDCompletionIdentifier arg; + GDScriptCompletionIdentifier arg; if (_guess_expression_type(context, op->arguments[i], p_line, arg)) { if (arg.value.get_type() != Variant::NIL && arg.value.get_type() != Variant::OBJECT) { // calling with object seems dangerous, i don' t know @@ -780,15 +785,15 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: } } } - } else if (op->op == GDParser::OperatorNode::OP_INDEX || op->op == GDParser::OperatorNode::OP_INDEX_NAMED) { + } else if (op->op == GDScriptParser::OperatorNode::OP_INDEX || op->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { - GDCompletionIdentifier p1; - GDCompletionIdentifier p2; + GDScriptCompletionIdentifier p1; + GDScriptCompletionIdentifier p2; - if (op->op == GDParser::OperatorNode::OP_INDEX_NAMED) { + if (op->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { - if (op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) { - String id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1])->name; + if (op->arguments[1]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { + String id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name; p2.type = Variant::STRING; p2.value = id; } @@ -802,9 +807,9 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: } } - if (op->arguments[0]->type == GDParser::Node::TYPE_ARRAY) { + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_ARRAY) { - const GDParser::ArrayNode *an = static_cast<const GDParser::ArrayNode *>(op->arguments[0]); + const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(op->arguments[0]); if (p2.value.is_num()) { int index = p2.value; if (index < 0 || index >= an->elements.size()) @@ -812,16 +817,16 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: return _guess_expression_type(context, an->elements[index], p_line, r_type); } - } else if (op->arguments[0]->type == GDParser::Node::TYPE_DICTIONARY) { + } else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_DICTIONARY) { - const GDParser::DictionaryNode *dn = static_cast<const GDParser::DictionaryNode *>(op->arguments[0]); + const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(op->arguments[0]); if (p2.value.get_type() == Variant::NIL) return false; for (int i = 0; i < dn->elements.size(); i++) { - GDCompletionIdentifier k; + GDScriptCompletionIdentifier k; if (!_guess_expression_type(context, dn->elements[i].key, p_line, k)) { @@ -853,9 +858,9 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: StringName base_type = p1.obj_type; - if (p1.obj_type == "GDNativeClass") { + if (p1.obj_type == "GDScriptNativeClass") { //native enum - Ref<GDNativeClass> gdn = p1.value; + Ref<GDScriptNativeClass> gdn = p1.value; if (gdn.is_valid()) { base_type = gdn->get_name(); @@ -916,24 +921,24 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: Variant::Operator vop = Variant::OP_MAX; switch (op->op) { - case GDParser::OperatorNode::OP_ADD: vop = Variant::OP_ADD; break; - case GDParser::OperatorNode::OP_SUB: vop = Variant::OP_SUBTRACT; break; - case GDParser::OperatorNode::OP_MUL: vop = Variant::OP_MULTIPLY; break; - case GDParser::OperatorNode::OP_DIV: vop = Variant::OP_DIVIDE; break; - case GDParser::OperatorNode::OP_MOD: vop = Variant::OP_MODULE; break; - case GDParser::OperatorNode::OP_SHIFT_LEFT: vop = Variant::OP_SHIFT_LEFT; break; - case GDParser::OperatorNode::OP_SHIFT_RIGHT: vop = Variant::OP_SHIFT_RIGHT; break; - case GDParser::OperatorNode::OP_BIT_AND: vop = Variant::OP_BIT_AND; break; - case GDParser::OperatorNode::OP_BIT_OR: vop = Variant::OP_BIT_OR; break; - case GDParser::OperatorNode::OP_BIT_XOR: vop = Variant::OP_BIT_XOR; break; + case GDScriptParser::OperatorNode::OP_ADD: vop = Variant::OP_ADD; break; + case GDScriptParser::OperatorNode::OP_SUB: vop = Variant::OP_SUBTRACT; break; + case GDScriptParser::OperatorNode::OP_MUL: vop = Variant::OP_MULTIPLY; break; + case GDScriptParser::OperatorNode::OP_DIV: vop = Variant::OP_DIVIDE; break; + case GDScriptParser::OperatorNode::OP_MOD: vop = Variant::OP_MODULE; break; + case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: vop = Variant::OP_SHIFT_LEFT; break; + case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: vop = Variant::OP_SHIFT_RIGHT; break; + case GDScriptParser::OperatorNode::OP_BIT_AND: vop = Variant::OP_BIT_AND; break; + case GDScriptParser::OperatorNode::OP_BIT_OR: vop = Variant::OP_BIT_OR; break; + case GDScriptParser::OperatorNode::OP_BIT_XOR: vop = Variant::OP_BIT_XOR; break; default: {} } if (vop == Variant::OP_MAX) return false; - GDCompletionIdentifier p1; - GDCompletionIdentifier p2; + GDScriptCompletionIdentifier p1; + GDScriptCompletionIdentifier p2; if (op->arguments[0]) { if (!_guess_expression_type(context, op->arguments[0], p_line, p1)) { @@ -980,15 +985,15 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: return false; } -static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type) { +static bool _guess_identifier_type_in_block(GDScriptCompletionContext &context, int p_line, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) { - if (context.block->if_condition && context.block->if_condition->type == GDParser::Node::TYPE_OPERATOR && static_cast<const GDParser::OperatorNode *>(context.block->if_condition)->op == GDParser::OperatorNode::OP_IS) { + if (context.block->if_condition && context.block->if_condition->type == GDScriptParser::Node::TYPE_OPERATOR && static_cast<const GDScriptParser::OperatorNode *>(context.block->if_condition)->op == GDScriptParser::OperatorNode::OP_IS) { //is used, check if identifier is in there! this helps resolve in blocks that are (if (identifier is value)): which are very common.. //super dirty hack, but very useful //credit: Zylann //TODO: this could be hacked to detect ANDed conditions too.. - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(context.block->if_condition); - if (op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER && static_cast<const GDParser::IdentifierNode *>(op->arguments[0])->name == p_identifier) { + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(context.block->if_condition); + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER && static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0])->name == p_identifier) { //bingo if (_guess_expression_type(context, op->arguments[1], op->line, r_type)) { return true; @@ -996,7 +1001,7 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ } } - GDCompletionIdentifier gdi = _get_native_class(context); + GDScriptCompletionIdentifier gdi = _get_native_class(context); if (gdi.obj_type != StringName()) { bool valid; Variant::Type t = ClassDB::get_property_type(gdi.obj_type, p_identifier, &valid); @@ -1022,7 +1027,7 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ } } - const GDParser::Node *last_assign = NULL; + const GDScriptParser::Node *last_assign = NULL; int last_assign_line = -1; for (int i = 0; i < context.block->statements.size(); i++) { @@ -1030,9 +1035,9 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ if (context.block->statements[i]->line > p_line) continue; - if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_LOCAL_VAR) { + if (context.block->statements[i]->type == GDScriptParser::BlockNode::TYPE_LOCAL_VAR) { - const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(context.block->statements[i]); + const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(context.block->statements[i]); if (lv->assign && lv->name == p_identifier) { @@ -1041,13 +1046,13 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ } } - if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_OPERATOR) { - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(context.block->statements[i]); - if (op->op == GDParser::OperatorNode::OP_ASSIGN) { + if (context.block->statements[i]->type == GDScriptParser::BlockNode::TYPE_OPERATOR) { + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(context.block->statements[i]); + if (op->op == GDScriptParser::OperatorNode::OP_ASSIGN) { - if (op->arguments.size() && op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER) { + if (op->arguments.size() && op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[0]); + const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0]); if (id->name == p_identifier) { @@ -1060,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); } @@ -1068,9 +1073,9 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ return false; } -static bool _guess_identifier_from_assignment_in_function(GDCompletionContext &context, int p_src_line, const StringName &p_identifier, const StringName &p_function, GDCompletionIdentifier &r_type) { +static bool _guess_identifier_from_assignment_in_function(GDScriptCompletionContext &context, int p_src_line, const StringName &p_identifier, const StringName &p_function, GDScriptCompletionIdentifier &r_type) { - const GDParser::FunctionNode *func = NULL; + const GDScriptParser::FunctionNode *func = NULL; for (int i = 0; i < context._class->functions.size(); i++) { if (context._class->functions[i]->name == p_function) { func = context._class->functions[i]; @@ -1087,13 +1092,13 @@ static bool _guess_identifier_from_assignment_in_function(GDCompletionContext &c break; } - if (func->body->statements[i]->type == GDParser::BlockNode::TYPE_OPERATOR) { - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(func->body->statements[i]); - if (op->op == GDParser::OperatorNode::OP_ASSIGN) { + if (func->body->statements[i]->type == GDScriptParser::BlockNode::TYPE_OPERATOR) { + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(func->body->statements[i]); + if (op->op == GDScriptParser::OperatorNode::OP_ASSIGN) { - if (op->arguments.size() && op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER) { + if (op->arguments.size() && op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[0]); + const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0]); if (id->name == p_identifier) { @@ -1107,15 +1112,15 @@ static bool _guess_identifier_from_assignment_in_function(GDCompletionContext &c return false; } -static bool _guess_identifier_type(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type, bool p_for_indexing) { +static bool _guess_identifier_type(GDScriptCompletionContext &context, int p_line, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type, bool p_for_indexing) { //go to block first - const GDParser::BlockNode *block = context.block; + const GDScriptParser::BlockNode *block = context.block; while (block) { - GDCompletionContext c = context; + GDScriptCompletionContext c = context; c.block = block; if (_guess_identifier_type_in_block(c, p_line, p_identifier, r_type)) { @@ -1139,7 +1144,7 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con } if (argindex != -1) { - GDCompletionIdentifier id = _get_native_class(context); + GDScriptCompletionIdentifier id = _get_native_class(context); if (id.type == Variant::OBJECT && id.obj_type != StringName()) { //this kinda sucks but meh @@ -1177,8 +1182,8 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con if (context._class->constant_expressions[i].identifier == p_identifier) { - ERR_FAIL_COND_V(context._class->constant_expressions[i].expression->type != GDParser::Node::TYPE_CONSTANT, false); - r_type = _get_type_from_variant(static_cast<const GDParser::ConstantNode *>(context._class->constant_expressions[i].expression)->value); + ERR_FAIL_COND_V(context._class->constant_expressions[i].expression->type != GDScriptParser::Node::TYPE_CONSTANT, false); + r_type = _get_type_from_variant(static_cast<const GDScriptParser::ConstantNode *>(context._class->constant_expressions[i].expression)->value); return true; } } @@ -1194,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) @@ -1268,7 +1275,7 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con return false; } -static void _find_identifiers_in_block(GDCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) { +static void _find_identifiers_in_block(GDScriptCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) { if (p_only_functions) return; @@ -1278,15 +1285,15 @@ static void _find_identifiers_in_block(GDCompletionContext &context, int p_line, if (context.block->statements[i]->line > p_line) continue; - if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_LOCAL_VAR) { + if (context.block->statements[i]->type == GDScriptParser::BlockNode::TYPE_LOCAL_VAR) { - const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(context.block->statements[i]); + const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(context.block->statements[i]); result.insert(lv->name.operator String()); } } } -static void _find_identifiers_in_class(GDCompletionContext &context, bool p_static, bool p_only_functions, Set<String> &result) { +static void _find_identifiers_in_class(GDScriptCompletionContext &context, bool p_static, bool p_only_functions, Set<String> &result) { if (!p_static && !p_only_functions) { @@ -1329,7 +1336,7 @@ static void _find_identifiers_in_class(GDCompletionContext &context, bool p_stat while (true) { Ref<GDScript> script = base; - Ref<GDNativeClass> nc = base; + Ref<GDScriptNativeClass> nc = base; if (script.is_valid()) { if (!p_static && !p_only_functions) { @@ -1344,7 +1351,7 @@ static void _find_identifiers_in_class(GDCompletionContext &context, bool p_stat } } - for (const Map<StringName, GDFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { if (!p_static || E->get()->is_static()) { if (E->get()->get_argument_count()) result.insert(E->key().operator String() + "("); @@ -1403,13 +1410,13 @@ static void _find_identifiers_in_class(GDCompletionContext &context, bool p_stat } } -static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) { +static void _find_identifiers(GDScriptCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) { - const GDParser::BlockNode *block = context.block; + const GDScriptParser::BlockNode *block = context.block; if (context.function) { - const GDParser::FunctionNode *f = context.function; + const GDScriptParser::FunctionNode *f = context.function; for (int i = 0; i < f->arguments.size(); i++) { result.insert(f->arguments[i].operator String()); @@ -1418,19 +1425,19 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o while (block) { - GDCompletionContext c = context; + GDScriptCompletionContext c = context; c.block = block; _find_identifiers_in_block(c, p_line, p_only_functions, result); block = block->parent_block; } - const GDParser::ClassNode *clss = context._class; + const GDScriptParser::ClassNode *clss = context._class; bool _static = context.function && context.function->_static; while (clss) { - GDCompletionContext c = context; + GDScriptCompletionContext c = context; c._class = clss; c.block = NULL; c.function = NULL; @@ -1438,9 +1445,9 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o clss = clss->owner; } - for (int i = 0; i < GDFunctions::FUNC_MAX; i++) { + for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { - result.insert(GDFunctions::get_func_name(GDFunctions::Function(i))); + result.insert(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))); } static const char *_type_names[Variant::VARIANT_MAX] = { @@ -1494,7 +1501,7 @@ static String _get_visual_datatype(const PropertyInfo &p_info, bool p_isarg = tr return Variant::get_type_name(p_info.type); } -static void _make_function_hint(const GDParser::FunctionNode *p_func, int p_argidx, String &arghint) { +static void _make_function_hint(const GDScriptParser::FunctionNode *p_func, int p_argidx, String &arghint) { arghint = "func " + p_func->name + "("; for (int i = 0; i < p_func->arguments.size(); i++) { @@ -1514,11 +1521,11 @@ static void _make_function_hint(const GDParser::FunctionNode *p_func, int p_argi if (defidx >= 0 && defidx < p_func->default_values.size()) { - if (p_func->default_values[defidx]->type == GDParser::Node::TYPE_OPERATOR) { + if (p_func->default_values[defidx]->type == GDScriptParser::Node::TYPE_OPERATOR) { - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_func->default_values[defidx]); - if (op->op == GDParser::OperatorNode::OP_ASSIGN) { - const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(op->arguments[1]); + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[defidx]); + if (op->op == GDScriptParser::OperatorNode::OP_ASSIGN) { + const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(op->arguments[1]); arghint += "=" + cn->value.get_construct_string(); } } else { @@ -1546,7 +1553,7 @@ void get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_lis } } -static void _find_type_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, const StringName &p_method, const GDCompletionIdentifier &id, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { +static void _find_type_arguments(GDScriptCompletionContext &context, const GDScriptParser::Node *p_node, int p_line, const StringName &p_method, const GDScriptCompletionIdentifier &id, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { //print_line("find type arguments?"); if (id.type == Variant::OBJECT && id.obj_type != StringName()) { @@ -1565,7 +1572,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N if (scr) { while (scr) { - for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { if (E->get()->is_static() && p_method == E->get()->get_name()) { arghint = "static func " + String(p_method) + "("; for (int i = 0; i < E->get()->get_argument_count(); i++) { @@ -1622,7 +1629,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N if (code != "") { //if there is code, parse it. This way is slower but updates in real-time - GDParser p; + GDScriptParser p; //Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false); Error err = p.parse(scr->get_source_code(), scr->get_path().get_base_dir(), true, "", false); @@ -1630,13 +1637,13 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N if (err == OK) { //print_line("checking the functions..."); //only if ok, otherwise use what is cached on the script - //GDParser::ClassNode *base = p. - const GDParser::Node *root = p.get_parse_tree(); - ERR_FAIL_COND(root->type != GDParser::Node::TYPE_CLASS); + //GDScriptParser::ClassNode *base = p. + const GDScriptParser::Node *root = p.get_parse_tree(); + ERR_FAIL_COND(root->type != GDScriptParser::Node::TYPE_CLASS); - const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root); + const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root); - const GDParser::FunctionNode *func = NULL; + const GDScriptParser::FunctionNode *func = NULL; bool st = false; for (int i = 0; i < cl->functions.size(); i++) { @@ -1674,10 +1681,10 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N int defidx = deffrom - i; - if (defidx >= 0 && defidx < func->default_values.size() && func->default_values[defidx]->type == GDParser::Node::TYPE_OPERATOR) { - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(func->default_values[defidx]); - if (op->op == GDParser::OperatorNode::OP_ASSIGN) { - const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(op->arguments[1]); + if (defidx >= 0 && defidx < func->default_values.size() && func->default_values[defidx]->type == GDScriptParser::Node::TYPE_OPERATOR) { + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(func->default_values[defidx]); + if (op->op == GDScriptParser::OperatorNode::OP_ASSIGN) { + const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(op->arguments[1]); arghint += "=" + cn->value.get_construct_string(); } } @@ -1698,7 +1705,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N if (code == "") { - for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { if (p_method == E->get()->get_name()) { arghint = "func " + String(p_method) + "("; for (int i = 0; i < E->get()->get_argument_count(); i++) { @@ -1807,8 +1814,8 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N } /*if (p_argidx==2) { - ERR_FAIL_COND(p_node->type!=GDParser::Node::TYPE_OPERATOR); - const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(p_node); + ERR_FAIL_COND(p_node->type!=GDScriptParser::Node::TYPE_OPERATOR); + const GDScriptParser::OperatorNode *op=static_cast<const GDScriptParser::OperatorNode *>(p_node); if (op->arguments.size()>) }*/ @@ -1883,30 +1890,30 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N } } -static void _find_call_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { +static void _find_call_arguments(GDScriptCompletionContext &context, const GDScriptParser::Node *p_node, int p_line, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { - if (!p_node || p_node->type != GDParser::Node::TYPE_OPERATOR) { + if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) { return; } - const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_node); + const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_node); - if (op->op != GDParser::OperatorNode::OP_CALL) { + if (op->op != GDScriptParser::OperatorNode::OP_CALL) { return; } - if (op->arguments[0]->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) { + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) { //complete built-in function - const GDParser::BuiltInFunctionNode *fn = static_cast<const GDParser::BuiltInFunctionNode *>(op->arguments[0]); - MethodInfo mi = GDFunctions::get_info(fn->function); + const GDScriptParser::BuiltInFunctionNode *fn = static_cast<const GDScriptParser::BuiltInFunctionNode *>(op->arguments[0]); + MethodInfo mi = GDScriptFunctions::get_info(fn->function); if (mi.name == "load" && bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) { get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), result); } - arghint = _get_visual_datatype(mi.return_val, false) + " " + GDFunctions::get_func_name(fn->function) + String("("); + arghint = _get_visual_datatype(mi.return_val, false) + " " + GDScriptFunctions::get_func_name(fn->function) + String("("); for (int i = 0; i < mi.arguments.size(); i++) { if (i > 0) arghint += ", "; @@ -1924,9 +1931,9 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N arghint += " "; arghint += ")"; - } else if (op->arguments[0]->type == GDParser::Node::TYPE_TYPE) { + } else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) { //complete constructor - const GDParser::TypeNode *tn = static_cast<const GDParser::TypeNode *>(op->arguments[0]); + const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(op->arguments[0]); List<MethodInfo> mil; Variant::get_constructor_list(tn->vtype, &mil); @@ -1957,11 +1964,11 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N arghint += ")"; } - } else if (op->arguments.size() >= 2 && op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) { + } else if (op->arguments.size() >= 2 && op->arguments[1]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { //make sure identifier exists... - const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1]); - if (op->arguments[0]->type == GDParser::Node::TYPE_SELF) { + const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1]); + if (op->arguments[0]->type == GDScriptParser::Node::TYPE_SELF) { //self, look up for (int i = 0; i < context._class->static_functions.size(); i++) { @@ -1986,10 +1993,10 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N while (true) { Ref<GDScript> script = base; - Ref<GDNativeClass> nc = base; + Ref<GDScriptNativeClass> nc = base; if (script.is_valid()) { - for (const Map<StringName, GDFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { if (E->key() == id->name) { @@ -2031,7 +2038,7 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N if (!(context.function && context.function->_static)) { - GDCompletionIdentifier ci; + GDScriptCompletionIdentifier ci; ci.type = Variant::OBJECT; ci.obj_type = nc->get_name(); if (!context._class->owner) @@ -2056,7 +2063,7 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N } else { //indexed lookup - GDCompletionIdentifier ci; + GDScriptCompletionIdentifier ci; if (_guess_expression_type(context, op->arguments[0], p_line, ci)) { _find_type_arguments(context, p_node, p_line, id->name, ci, p_argidx, result, r_forced, arghint); @@ -2068,13 +2075,13 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { - GDParser p; + GDScriptParser p; p.parse(p_code, p_base_path, false, "", true); bool isfunction = false; Set<String> options; r_forced = false; - GDCompletionContext context; + GDScriptCompletionContext context; context._class = p.get_completion_class(); context.block = p.get_completion_block(); context.function = p.get_completion_function(); @@ -2083,9 +2090,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base switch (p.get_completion_type()) { - case GDParser::COMPLETION_NONE: { + case GDScriptParser::COMPLETION_NONE: { } break; - case GDParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: { + case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: { List<StringName> constants; Variant::get_numeric_constants_for_type(p.get_completion_built_in_constant(), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { @@ -2093,16 +2100,16 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } } break; - case GDParser::COMPLETION_FUNCTION: + case GDScriptParser::COMPLETION_FUNCTION: isfunction = true; - case GDParser::COMPLETION_IDENTIFIER: { + case GDScriptParser::COMPLETION_IDENTIFIER: { _find_identifiers(context, p.get_completion_line(), isfunction, options); } break; - case GDParser::COMPLETION_PARENT_FUNCTION: { + case GDScriptParser::COMPLETION_PARENT_FUNCTION: { } break; - case GDParser::COMPLETION_GET_NODE: { + case GDScriptParser::COMPLETION_GET_NODE: { if (p_owner) { List<String> opts; @@ -2123,20 +2130,20 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } } } break; - case GDParser::COMPLETION_METHOD: + case GDScriptParser::COMPLETION_METHOD: isfunction = true; - case GDParser::COMPLETION_INDEX: { + case GDScriptParser::COMPLETION_INDEX: { - const GDParser::Node *node = p.get_completion_node(); - if (node->type != GDParser::Node::TYPE_OPERATOR) + const GDScriptParser::Node *node = p.get_completion_node(); + if (node->type != GDScriptParser::Node::TYPE_OPERATOR) break; - GDCompletionIdentifier t; - if (_guess_expression_type(context, static_cast<const GDParser::OperatorNode *>(node)->arguments[0], p.get_completion_line(), t, true)) { + GDScriptCompletionIdentifier t; + if (_guess_expression_type(context, static_cast<const GDScriptParser::OperatorNode *>(node)->arguments[0], p.get_completion_line(), t, true)) { - if (t.type == Variant::OBJECT && t.obj_type == "GDNativeClass") { + if (t.type == Variant::OBJECT && t.obj_type == "GDScriptNativeClass") { //native enum - Ref<GDNativeClass> gdn = t.value; + Ref<GDScriptNativeClass> gdn = t.value; if (gdn.is_valid()) { StringName cn = gdn->get_name(); List<String> cnames; @@ -2172,7 +2179,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base options.insert(E->key()); } } - for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { if (E->get()->is_static()) options.insert(E->key()); } @@ -2203,17 +2210,17 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base if (code != "") { //if there is code, parse it. This way is slower but updates in real-time - GDParser p; + GDScriptParser p; Error err = p.parse(scr->get_source_code(), scr->get_path().get_base_dir(), true, "", false); if (err == OK) { //only if ok, otherwise use what is cached on the script - //GDParser::ClassNode *base = p. - const GDParser::Node *root = p.get_parse_tree(); - ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, ERR_PARSE_ERROR); + //GDScriptParser::ClassNode *base = p. + const GDScriptParser::Node *root = p.get_parse_tree(); + ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, ERR_PARSE_ERROR); - const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root); + const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root); for (int i = 0; i < cl->functions.size(); i++) { @@ -2255,7 +2262,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base options.insert(E->key()); } } - for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { + for (const Map<StringName, GDScriptFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) { if (E->get()->get_argument_count()) options.insert(String(E->key()) + "()"); else @@ -2334,13 +2341,13 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } } break; - case GDParser::COMPLETION_CALL_ARGUMENTS: { + case GDScriptParser::COMPLETION_CALL_ARGUMENTS: { _find_call_arguments(context, p.get_completion_node(), p.get_completion_line(), p.get_completion_argument_index(), options, r_forced, r_call_hint); } break; - case GDParser::COMPLETION_VIRTUAL_FUNC: { + case GDScriptParser::COMPLETION_VIRTUAL_FUNC: { - GDCompletionIdentifier cid = _get_native_class(context); + GDScriptCompletionIdentifier cid = _get_native_class(context); if (cid.obj_type != StringName()) { List<MethodInfo> vm; @@ -2369,11 +2376,11 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } } } break; - case GDParser::COMPLETION_YIELD: { + case GDScriptParser::COMPLETION_YIELD: { - const GDParser::Node *node = p.get_completion_node(); + const GDScriptParser::Node *node = p.get_completion_node(); - GDCompletionIdentifier t; + GDScriptCompletionIdentifier t; if (!_guess_expression_type(context, node, p.get_completion_line(), t)) break; @@ -2388,15 +2395,15 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } } break; - case GDParser::COMPLETION_RESOURCE_PATH: { + case GDScriptParser::COMPLETION_RESOURCE_PATH: { if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options); } break; - case GDParser::COMPLETION_ASSIGN: { + case GDScriptParser::COMPLETION_ASSIGN: { #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) - GDCompletionIdentifier ci; + GDScriptCompletionIdentifier ci; if (_guess_expression_type(context, p.get_completion_node(), p.get_completion_line(), ci)) { String enumeration = ci.enumeration; @@ -2549,8 +2556,8 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } - for (int i = 0; i < GDFunctions::FUNC_MAX; i++) { - if (GDFunctions::get_func_name(GDFunctions::Function(i)) == p_symbol) { + for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { + if (GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i)) == p_symbol) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD; r_result.class_name = "@GDScript"; r_result.class_member = p_symbol; @@ -2558,13 +2565,13 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } - GDParser p; + GDScriptParser p; p.parse(p_code, p_base_path, false, "", true); - if (p.get_completion_type() == GDParser::COMPLETION_NONE) + if (p.get_completion_type() == GDScriptParser::COMPLETION_NONE) return ERR_CANT_RESOLVE; - GDCompletionContext context; + GDScriptCompletionContext context; context._class = p.get_completion_class(); context.block = p.get_completion_block(); @@ -2575,10 +2582,10 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol switch (p.get_completion_type()) { - case GDParser::COMPLETION_GET_NODE: - case GDParser::COMPLETION_NONE: { + case GDScriptParser::COMPLETION_GET_NODE: + case GDScriptParser::COMPLETION_NONE: { } break; - case GDParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: { + case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT; r_result.class_name = Variant::get_type_name(p.get_completion_built_in_constant()); @@ -2586,7 +2593,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol return OK; } break; - case GDParser::COMPLETION_FUNCTION: { + case GDScriptParser::COMPLETION_FUNCTION: { if (context._class && context._class->functions.size()) { for (int i = 0; i < context._class->functions.size(); i++) { @@ -2611,7 +2618,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol parent = parent->get_base(); } - GDCompletionIdentifier identifier = _get_native_class(context); + GDScriptCompletionIdentifier identifier = _get_native_class(context); print_line("identifier: " + String(identifier.obj_type)); if (ClassDB::has_method(identifier.obj_type, p_symbol)) { @@ -2623,7 +2630,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } break; - case GDParser::COMPLETION_IDENTIFIER: { + case GDScriptParser::COMPLETION_IDENTIFIER: { //check if a function if (p.get_completion_identifier_is_function()) { @@ -2650,7 +2657,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol parent = parent->get_base(); } - GDCompletionIdentifier identifier = _get_native_class(context); + GDScriptCompletionIdentifier identifier = _get_native_class(context); if (ClassDB::has_method(identifier.obj_type, p_symbol)) { @@ -2661,7 +2668,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } else { - GDCompletionIdentifier gdi = _get_native_class(context); + GDScriptCompletionIdentifier gdi = _get_native_class(context); if (gdi.obj_type != StringName()) { bool valid; Variant::Type t = ClassDB::get_property_type(gdi.obj_type, p_symbol, &valid); @@ -2673,7 +2680,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } - const GDParser::BlockNode *block = context.block; + const GDScriptParser::BlockNode *block = context.block; //search in blocks going up (local var?) while (block) { @@ -2682,9 +2689,9 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol if (block->statements[i]->line > p.get_completion_line()) continue; - if (block->statements[i]->type == GDParser::BlockNode::TYPE_LOCAL_VAR) { + if (block->statements[i]->type == GDScriptParser::BlockNode::TYPE_LOCAL_VAR) { - const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(block->statements[i]); + const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(block->statements[i]); if (lv->assign && lv->name == p_symbol) { @@ -2769,53 +2776,53 @@ 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<GDScriptNativeClass>(obj)) { + r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS; + r_result.class_name = Object::cast_to<GDScriptNativeClass>(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 = "@GlobalScope"; + r_result.class_member = p_symbol; + return OK; } } } } break; - case GDParser::COMPLETION_PARENT_FUNCTION: { + case GDScriptParser::COMPLETION_PARENT_FUNCTION: { } break; - case GDParser::COMPLETION_METHOD: + case GDScriptParser::COMPLETION_METHOD: isfunction = true; - case GDParser::COMPLETION_INDEX: { + case GDScriptParser::COMPLETION_INDEX: { - const GDParser::Node *node = p.get_completion_node(); - if (node->type != GDParser::Node::TYPE_OPERATOR) + const GDScriptParser::Node *node = p.get_completion_node(); + if (node->type != GDScriptParser::Node::TYPE_OPERATOR) break; - GDCompletionIdentifier t; - if (_guess_expression_type(context, static_cast<const GDParser::OperatorNode *>(node)->arguments[0], p.get_completion_line(), t)) { + GDScriptCompletionIdentifier t; + if (_guess_expression_type(context, static_cast<const GDScriptParser::OperatorNode *>(node)->arguments[0], p.get_completion_line(), t)) { - if (t.type == Variant::OBJECT && t.obj_type == "GDNativeClass") { + if (t.type == Variant::OBJECT && t.obj_type == "GDScriptNativeClass") { //native enum - Ref<GDNativeClass> gdn = t.value; + Ref<GDScriptNativeClass> gdn = t.value; if (gdn.is_valid()) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT; r_result.class_name = gdn->get_name(); @@ -2907,13 +2914,13 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } break; - case GDParser::COMPLETION_CALL_ARGUMENTS: { + case GDScriptParser::COMPLETION_CALL_ARGUMENTS: { return ERR_CANT_RESOLVE; } break; - case GDParser::COMPLETION_VIRTUAL_FUNC: { + case GDScriptParser::COMPLETION_VIRTUAL_FUNC: { - GDCompletionIdentifier cid = _get_native_class(context); + GDScriptCompletionIdentifier cid = _get_native_class(context); if (cid.obj_type != StringName()) { List<MethodInfo> vm; @@ -2930,7 +2937,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } } break; - case GDParser::COMPLETION_YIELD: { + case GDScriptParser::COMPLETION_YIELD: { return ERR_CANT_RESOLVE; diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gdscript_function.cpp index ce503b62f2..765a76fec4 100644 --- a/modules/gdscript/gd_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_function.cpp */ +/* gdscript_function.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,13 +27,13 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_function.h" +#include "gdscript_function.h" -#include "gd_functions.h" -#include "gd_script.h" +#include "gdscript.h" +#include "gdscript_functions.h" #include "os/os.h" -Variant *GDFunction::_get_variant(int p_address, GDInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const { +Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const { int address = p_address & ADDR_MASK; @@ -85,7 +85,7 @@ Variant *GDFunction::_get_variant(int p_address, GDInstance *p_instance, GDScrip o = o->_owner; } - ERR_EXPLAIN("GDCompiler bug.."); + ERR_EXPLAIN("GDScriptCompiler bug.."); ERR_FAIL_V(NULL); } break; case ADDR_TYPE_LOCAL_CONSTANT: { @@ -117,7 +117,7 @@ Variant *GDFunction::_get_variant(int p_address, GDInstance *p_instance, GDScrip return NULL; } -String GDFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const { +String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const { String err_text; @@ -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, \ @@ -231,7 +231,7 @@ static String _get_var_type(const Variant *p_type) { #define OPCODE_OUT break #endif -Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state) { +Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state) { OPCODES_TABLE; @@ -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); @@ -478,7 +479,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } else { - GDNativeClass *nc = Object::cast_to<GDNativeClass>(obj_B); + GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(obj_B); #ifdef DEBUG_ENABLED if (!nc) { @@ -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,13 +844,14 @@ 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); - GDFunctions::Function func = GDFunctions::Function(_code_ptr[ip + 1]); + GDScriptFunctions::Function func = GDScriptFunctions::Function(_code_ptr[ip + 1]); int argc = _code_ptr[ip + 2]; GD_ERR_BREAK(argc < 0); @@ -853,12 +868,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a Variant::CallError err; - GDFunctions::call(func, (const Variant **)argptrs, argc, *dst, err); + GDScriptFunctions::call(func, (const Variant **)argptrs, argc, *dst, err); #ifdef DEBUG_ENABLED if (err.error != Variant::CallError::CALL_OK) { - String methodstr = GDFunctions::get_func_name(func); + String methodstr = GDScriptFunctions::get_func_name(func); if (dst->get_type() == Variant::STRING) { //call provided error string err_text = "Error calling built-in function '" + methodstr + "': " + String(*dst); @@ -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); @@ -904,7 +921,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a const GDScript *gds = _script; - const Map<StringName, GDFunction *>::Element *E = NULL; + const Map<StringName, GDScriptFunction *>::Element *E = NULL; while (gds->base.ptr()) { gds = gds->base.ptr(); E = gds->member_functions.find(*methodname); @@ -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) { @@ -961,7 +979,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a CHECK_SPACE(2); } - Ref<GDFunctionState> gdfs = memnew(GDFunctionState); + Ref<GDScriptFunctionState> gdfs = memnew(GDScriptFunctionState); gdfs->function = this; gdfs->state.stack.resize(alloca_size); @@ -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; @@ -1291,43 +1321,43 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a return retvalue; } -const int *GDFunction::get_code() const { +const int *GDScriptFunction::get_code() const { return _code_ptr; } -int GDFunction::get_code_size() const { +int GDScriptFunction::get_code_size() const { return _code_size; } -Variant GDFunction::get_constant(int p_idx) const { +Variant GDScriptFunction::get_constant(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, constants.size(), "<errconst>"); return constants[p_idx]; } -StringName GDFunction::get_global_name(int p_idx) const { +StringName GDScriptFunction::get_global_name(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, global_names.size(), "<errgname>"); return global_names[p_idx]; } -int GDFunction::get_default_argument_count() const { +int GDScriptFunction::get_default_argument_count() const { return default_arguments.size(); } -int GDFunction::get_default_argument_addr(int p_idx) const { +int GDScriptFunction::get_default_argument_addr(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), -1); return default_arguments[p_idx]; } -StringName GDFunction::get_name() const { +StringName GDScriptFunction::get_name() const { return name; } -int GDFunction::get_max_stack_size() const { +int GDScriptFunction::get_max_stack_size() const { return _stack_size; } @@ -1350,7 +1380,7 @@ struct _GDFKCS { } }; -void GDFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const { +void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const { int oc = 0; Map<StringName, _GDFKC> sdmap; @@ -1402,7 +1432,7 @@ void GDFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, } } -GDFunction::GDFunction() +GDScriptFunction::GDScriptFunction() : function_list(this) { _stack_size = 0; @@ -1434,7 +1464,7 @@ GDFunction::GDFunction() #endif } -GDFunction::~GDFunction() { +GDScriptFunction::~GDScriptFunction() { #ifdef DEBUG_ENABLED if (GDScriptLanguage::get_singleton()->lock) { GDScriptLanguage::get_singleton()->lock->lock(); @@ -1449,7 +1479,7 @@ GDFunction::~GDFunction() { ///////////////////// -Variant GDFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { #ifdef DEBUG_ENABLED if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { @@ -1484,7 +1514,7 @@ Variant GDFunctionState::_signal_callback(const Variant **p_args, int p_argcount arg = extra_args; } - Ref<GDFunctionState> self = *p_args[p_argcount - 1]; + Ref<GDScriptFunctionState> self = *p_args[p_argcount - 1]; if (self.is_null()) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; @@ -1498,10 +1528,10 @@ Variant GDFunctionState::_signal_callback(const Variant **p_args, int p_argcount bool completed = true; - // If the return value is a GDFunctionState reference, + // If the return value is a GDScriptFunctionState reference, // then the function did yield again after resuming. if (ret.is_ref()) { - GDFunctionState *gdfs = Object::cast_to<GDFunctionState>(ret); + GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); if (gdfs && gdfs->function == function) completed = false; } @@ -1516,7 +1546,7 @@ Variant GDFunctionState::_signal_callback(const Variant **p_args, int p_argcount return ret; } -bool GDFunctionState::is_valid(bool p_extended_check) const { +bool GDScriptFunctionState::is_valid(bool p_extended_check) const { if (function == NULL) return false; @@ -1533,7 +1563,7 @@ bool GDFunctionState::is_valid(bool p_extended_check) const { return true; } -Variant GDFunctionState::resume(const Variant &p_arg) { +Variant GDScriptFunctionState::resume(const Variant &p_arg) { ERR_FAIL_COND_V(!function, Variant()); #ifdef DEBUG_ENABLED @@ -1554,10 +1584,10 @@ Variant GDFunctionState::resume(const Variant &p_arg) { bool completed = true; - // If the return value is a GDFunctionState reference, + // If the return value is a GDScriptFunctionState reference, // then the function did yield again after resuming. if (ret.is_ref()) { - GDFunctionState *gdfs = Object::cast_to<GDFunctionState>(ret); + GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); if (gdfs && gdfs->function == function) completed = false; } @@ -1572,21 +1602,21 @@ Variant GDFunctionState::resume(const Variant &p_arg) { return ret; } -void GDFunctionState::_bind_methods() { +void GDScriptFunctionState::_bind_methods() { - ClassDB::bind_method(D_METHOD("resume", "arg"), &GDFunctionState::resume, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDFunctionState::is_valid, DEFVAL(false)); - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDFunctionState::_signal_callback, MethodInfo("_signal_callback")); + ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false)); + ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDScriptFunctionState::_signal_callback, MethodInfo("_signal_callback")); ADD_SIGNAL(MethodInfo("completed", PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); } -GDFunctionState::GDFunctionState() { +GDScriptFunctionState::GDScriptFunctionState() { function = NULL; } -GDFunctionState::~GDFunctionState() { +GDScriptFunctionState::~GDScriptFunctionState() { if (function != NULL) { //never called, deinitialize stack diff --git a/modules/gdscript/gd_function.h b/modules/gdscript/gdscript_function.h index bf5ff5f8da..03fd5d52dc 100644 --- a/modules/gdscript/gd_function.h +++ b/modules/gdscript/gdscript_function.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_function.h */ +/* gdscript_function.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,8 +27,8 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_FUNCTION_H -#define GD_FUNCTION_H +#ifndef GDSCRIPT_FUNCTION_H +#define GDSCRIPT_FUNCTION_H #include "os/thread.h" #include "pair.h" @@ -38,10 +38,10 @@ #include "string_db.h" #include "variant.h" -class GDInstance; +class GDScriptInstance; class GDScript; -class GDFunction { +class GDScriptFunction { public: enum Opcode { OPCODE_OPERATOR, @@ -111,7 +111,7 @@ public: }; private: - friend class GDCompiler; + friend class GDScriptCompiler; StringName source; @@ -145,12 +145,12 @@ private: List<StackDebug> stack_debug; - _FORCE_INLINE_ Variant *_get_variant(int p_address, GDInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const; + _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const; _FORCE_INLINE_ String _get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const; friend class GDScriptLanguage; - SelfList<GDFunction> function_list; + SelfList<GDScriptFunction> function_list; #ifdef DEBUG_ENABLED CharString func_cname; const char *_func_cname; @@ -176,7 +176,7 @@ public: ObjectID instance_id; //by debug only ObjectID script_id; - GDInstance *instance; + GDScriptInstance *instance; Vector<uint8_t> stack; int stack_size; Variant self; @@ -219,19 +219,19 @@ public: return default_arguments[p_idx]; } - Variant call(GDInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL); + Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL); _FORCE_INLINE_ ScriptInstance::RPCMode get_rpc_mode() const { return rpc_mode; } - GDFunction(); - ~GDFunction(); + GDScriptFunction(); + ~GDScriptFunction(); }; -class GDFunctionState : public Reference { +class GDScriptFunctionState : public Reference { - GDCLASS(GDFunctionState, Reference); - friend class GDFunction; - GDFunction *function; - GDFunction::CallState state; + GDCLASS(GDScriptFunctionState, Reference); + friend class GDScriptFunction; + GDScriptFunction *function; + GDScriptFunction::CallState state; Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error); protected: @@ -240,8 +240,8 @@ protected: public: bool is_valid(bool p_extended_check = false) const; Variant resume(const Variant &p_arg = Variant()); - GDFunctionState(); - ~GDFunctionState(); + GDScriptFunctionState(); + ~GDScriptFunctionState(); }; -#endif // GD_FUNCTION_H +#endif // GDSCRIPT_FUNCTION_H diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gdscript_functions.cpp index b43ec409a1..467dbf3e56 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_functions.cpp */ +/* gdscript_functions.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,10 +27,11 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_functions.h" +#include "gdscript_functions.h" + #include "class_db.h" #include "func_ref.h" -#include "gd_script.h" +#include "gdscript.h" #include "io/json.h" #include "io/marshalls.h" #include "math_funcs.h" @@ -38,7 +39,7 @@ #include "reference.h" #include "variant_parser.h" -const char *GDFunctions::get_func_name(Function p_func) { +const char *GDScriptFunctions::get_func_name(Function p_func) { ERR_FAIL_INDEX_V(p_func, FUNC_MAX, ""); @@ -123,7 +124,7 @@ const char *GDFunctions::get_func_name(Function p_func) { return _names[p_func]; } -void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error) { +void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error) { r_error.error = Variant::CallError::CALL_OK; #ifdef DEBUG_ENABLED @@ -899,7 +900,7 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, return; } else { - GDInstance *ins = static_cast<GDInstance *>(obj->get_script_instance()); + GDScriptInstance *ins = static_cast<GDScriptInstance *>(obj->get_script_instance()); Ref<GDScript> base = ins->get_script(); if (base.is_null()) { @@ -1030,7 +1031,7 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, r_ret = gdscr->_new(NULL, 0, r_error); - GDInstance *ins = static_cast<GDInstance *>(static_cast<Object *>(r_ret)->get_script_instance()); + GDScriptInstance *ins = static_cast<GDScriptInstance *>(static_cast<Object *>(r_ret)->get_script_instance()); Ref<GDScript> gd_ref = ins->get_script(); for (Map<StringName, GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) { @@ -1254,7 +1255,7 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, } } -bool GDFunctions::is_deterministic(Function p_func) { +bool GDScriptFunctions::is_deterministic(Function p_func) { //man i couldn't have chosen a worse function name, //way too controversial.. @@ -1317,7 +1318,7 @@ bool GDFunctions::is_deterministic(Function p_func) { return false; } -MethodInfo GDFunctions::get_info(Function p_func) { +MethodInfo GDScriptFunctions::get_info(Function p_func) { #ifdef TOOLS_ENABLED //using a switch, so the compiler generates a jumptable diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gdscript_functions.h index 0de09f2e71..ecbede83a8 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_functions.h */ +/* gdscript_functions.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,12 +27,12 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_FUNCTIONS_H -#define GD_FUNCTIONS_H +#ifndef GDSCRIPT_FUNCTIONS_H +#define GDSCRIPT_FUNCTIONS_H #include "variant.h" -class GDFunctions { +class GDScriptFunctions { public: enum Function { MATH_SIN, @@ -120,4 +120,4 @@ public: static MethodInfo get_info(Function p_func); }; -#endif // GD_FUNCTIONS_H +#endif // GDSCRIPT_FUNCTIONS_H diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 94385dc0d0..29b9865b1d 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_parser.cpp */ +/* gdscript_parser.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,15 +27,16 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_parser.h" -#include "gd_script.h" +#include "gdscript_parser.h" + +#include "gdscript.h" #include "io/resource_loader.h" #include "os/file_access.h" #include "print_string.h" #include "script_language.h" template <class T> -T *GDParser::alloc_node() { +T *GDScriptParser::alloc_node() { T *t = memnew(T); @@ -50,21 +51,21 @@ T *GDParser::alloc_node() { return t; } -bool GDParser::_end_statement() { +bool GDScriptParser::_end_statement() { - if (tokenizer->get_token() == GDTokenizer::TK_SEMICOLON) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) { tokenizer->advance(); return true; //handle next - } else if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE || tokenizer->get_token() == GDTokenizer::TK_EOF) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE || tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { return true; //will be handled properly } return false; } -bool GDParser::_enter_indent_block(BlockNode *p_block) { +bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { - if (tokenizer->get_token() != GDTokenizer::TK_COLON) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) { // report location at the previous token (on the previous line) int error_line = tokenizer->get_token_line(-1); int error_column = tokenizer->get_token_column(-1); @@ -73,7 +74,7 @@ bool GDParser::_enter_indent_block(BlockNode *p_block) { } tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) { // be more python-like int current = tab_level.back()->get(); @@ -85,10 +86,10 @@ bool GDParser::_enter_indent_block(BlockNode *p_block) { while (true) { - if (tokenizer->get_token() != GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) { return false; //wtf - } else if (tokenizer->get_token(1) != GDTokenizer::TK_NEWLINE) { + } else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) { int indent = tokenizer->get_token_line_indent(); int current = tab_level.back()->get(); @@ -113,9 +114,9 @@ bool GDParser::_enter_indent_block(BlockNode *p_block) { } } -bool GDParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete) { +bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete) { - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); } else { @@ -124,10 +125,10 @@ bool GDParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_s while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { _make_completable_call(argidx); completion_node = p_parent; - } else if (tokenizer->get_token() == GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING && tokenizer->get_token(1) == GDTokenizer::TK_CURSOR) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING && tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR) { //completing a string argument.. completion_cursor = tokenizer->get_token_constant(); @@ -143,13 +144,13 @@ bool GDParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_s p_args.push_back(arg); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); break; - } else if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { - if (tokenizer->get_token(1) == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expression expected"); return false; @@ -169,7 +170,7 @@ bool GDParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_s return true; } -void GDParser::_make_completable_call(int p_arg) { +void GDScriptParser::_make_completable_call(int p_arg) { completion_cursor = StringName(); completion_type = COMPLETION_CALL_ARGUMENTS; @@ -182,14 +183,14 @@ void GDParser::_make_completable_call(int p_arg) { tokenizer->advance(); } -bool GDParser::_get_completable_identifier(CompletionType p_type, StringName &identifier) { +bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringName &identifier) { identifier = StringName(); if (tokenizer->is_token_literal()) { identifier = tokenizer->get_token_literal(); tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { completion_cursor = identifier; completion_type = p_type; @@ -206,7 +207,7 @@ bool GDParser::_get_completable_identifier(CompletionType p_type, StringName &id tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { completion_ident_is_call = true; } return true; @@ -215,7 +216,7 @@ bool GDParser::_get_completable_identifier(CompletionType p_type, StringName &id return false; } -GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign, bool p_parsing_constant) { +GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign, bool p_parsing_constant) { //Vector<Node*> expressions; //Vector<OperatorNode::Operator> operators; @@ -234,12 +235,12 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (parenthesis > 0) { //remove empty space (only allowed if inside parenthesis - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); } } - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { //subexpression () tokenizer->advance(); parenthesis++; @@ -248,7 +249,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (!subexpr) return NULL; - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in expression"); return NULL; @@ -256,7 +257,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool tokenizer->advance(); expr = subexpr; - } else if (tokenizer->get_token() == GDTokenizer::TK_DOLLAR) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_DOLLAR) { tokenizer->advance(); String path; @@ -267,7 +268,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool while (!done) { switch (tokenizer->get_token()) { - case GDTokenizer::TK_CURSOR: { + case GDScriptTokenizer::TK_CURSOR: { completion_cursor = StringName(); completion_type = COMPLETION_GET_NODE; completion_class = current_class; @@ -279,7 +280,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool completion_found = true; tokenizer->advance(); } break; - case GDTokenizer::TK_CONSTANT: { + case GDScriptTokenizer::TK_CONSTANT: { if (!need_identifier) { done = true; @@ -296,7 +297,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool need_identifier = false; } break; - case GDTokenizer::TK_OP_DIV: { + case GDScriptTokenizer::TK_OP_DIV: { if (need_identifier) { done = true; @@ -344,49 +345,56 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expr = op; - } else if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { tokenizer->advance(); continue; //no point in cursor in the middle of expression - } else if (tokenizer->get_token() == GDTokenizer::TK_CONSTANT) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) { //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = tokenizer->get_token_constant(); tokenizer->advance(); expr = constant; - } else if (tokenizer->get_token() == GDTokenizer::TK_CONST_PI) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_PI) { //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_PI; tokenizer->advance(); expr = constant; - } else if (tokenizer->get_token() == GDTokenizer::TK_CONST_INF) { + } else if (tokenizer->get_token() == GDScriptTokenizer::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() == GDScriptTokenizer::TK_CONST_INF) { //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_INF; tokenizer->advance(); expr = constant; - } else if (tokenizer->get_token() == GDTokenizer::TK_CONST_NAN) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_NAN) { //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_NAN; tokenizer->advance(); expr = constant; - } else if (tokenizer->get_token() == GDTokenizer::TK_PR_PRELOAD) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_PRELOAD) { //constant defined by tokenizer tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { _set_error("Expected '(' after 'preload'"); return NULL; } tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { completion_cursor = StringName(); completion_node = p_parent; completion_type = COMPLETION_RESOURCE_PATH; @@ -466,7 +474,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool } } - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' after 'preload' path"); return NULL; } @@ -476,12 +484,12 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool constant->value = res; expr = constant; - } else if (tokenizer->get_token() == GDTokenizer::TK_PR_YIELD) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_YIELD) { //constant defined by tokenizer tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { _set_error("Expected '(' after 'yield'"); return NULL; } @@ -491,11 +499,11 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool OperatorNode *yield = alloc_node<OperatorNode>(); yield->op = OperatorNode::OP_YIELD; - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { expr = yield; tokenizer->advance(); } else { @@ -507,14 +515,14 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return NULL; yield->arguments.push_back(object); - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { _set_error("Expected ',' after first argument of 'yield'"); return NULL; } tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { completion_cursor = StringName(); completion_node = object; @@ -533,7 +541,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return NULL; yield->arguments.push_back(signal); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' after second argument of 'yield'"); return NULL; } @@ -545,7 +553,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expr = yield; } - } else if (tokenizer->get_token() == GDTokenizer::TK_SELF) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_SELF) { if (p_static) { _set_error("'self'' not allowed in static function or constant expression"); @@ -555,7 +563,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool SelfNode *self = alloc_node<SelfNode>(); tokenizer->advance(); expr = self; - } else if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDTokenizer::TK_PERIOD) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) { Variant::Type bi_type = tokenizer->get_token_type(); tokenizer->advance(2); @@ -582,20 +590,20 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool cn->value = Variant::get_numeric_constant_value(bi_type, identifier); expr = cn; - } else if (tokenizer->get_token(1) == GDTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) { + } else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name //function or constructor OperatorNode *op = alloc_node<OperatorNode>(); op->op = OperatorNode::OP_CALL; - if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_TYPE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) { TypeNode *tn = alloc_node<TypeNode>(); tn->vtype = tokenizer->get_token_type(); op->arguments.push_back(tn); tokenizer->advance(2); - } else if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_FUNC) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>(); bn->function = tokenizer->get_token_built_in_func(); @@ -616,7 +624,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool tokenizer->advance(1); } - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { _make_completable_call(0); completion_node = op; } @@ -661,7 +669,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expr = id; } - } else if (tokenizer->get_token() == GDTokenizer::TK_OP_ADD || tokenizer->get_token() == GDTokenizer::TK_OP_SUB || tokenizer->get_token() == GDTokenizer::TK_OP_NOT || tokenizer->get_token() == GDTokenizer::TK_OP_BIT_INVERT) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ADD || tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB || tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT || tokenizer->get_token() == GDScriptTokenizer::TK_OP_BIT_INVERT) { //single prefix operators like !expr +expr -expr ++expr --expr alloc_node<OperatorNode>(); @@ -669,16 +677,16 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool e.is_op = true; switch (tokenizer->get_token()) { - case GDTokenizer::TK_OP_ADD: e.op = OperatorNode::OP_POS; break; - case GDTokenizer::TK_OP_SUB: e.op = OperatorNode::OP_NEG; break; - case GDTokenizer::TK_OP_NOT: e.op = OperatorNode::OP_NOT; break; - case GDTokenizer::TK_OP_BIT_INVERT: e.op = OperatorNode::OP_BIT_INVERT; break; + case GDScriptTokenizer::TK_OP_ADD: e.op = OperatorNode::OP_POS; break; + case GDScriptTokenizer::TK_OP_SUB: e.op = OperatorNode::OP_NEG; break; + case GDScriptTokenizer::TK_OP_NOT: e.op = OperatorNode::OP_NOT; break; + case GDScriptTokenizer::TK_OP_BIT_INVERT: e.op = OperatorNode::OP_BIT_INVERT; break; default: {} } tokenizer->advance(); - if (e.op != OperatorNode::OP_NOT && tokenizer->get_token() == GDTokenizer::TK_OP_NOT) { + if (e.op != OperatorNode::OP_NOT && tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT) { _set_error("Misplaced 'not'."); return NULL; } @@ -693,7 +701,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool op->arguments.push_back(subexpr); expr=op;*/ - } else if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_OPEN) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) { // array tokenizer->advance(); @@ -702,18 +710,18 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_EOF) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { _set_error("Unterminated array"); return NULL; - } else if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(); break; - } else if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); //ignore newline - } else if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { if (!expecting_comma) { _set_error("expression or ']' expected"); return NULL; @@ -736,7 +744,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool } expr = arr; - } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_OPEN) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_OPEN) { // array tokenizer->advance(); @@ -758,12 +766,12 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_EOF) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { _set_error("Unterminated dictionary"); return NULL; - } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { if (expecting == DICT_EXPECT_COLON) { _set_error("':' expected"); @@ -775,10 +783,10 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool } tokenizer->advance(); break; - } else if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); //ignore newline - } else if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { if (expecting == DICT_EXPECT_KEY) { _set_error("key or '}' expected"); @@ -796,7 +804,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expecting = DICT_EXPECT_KEY; tokenizer->advance(); //ignore newline - } else if (tokenizer->get_token() == GDTokenizer::TK_COLON) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { if (expecting == DICT_EXPECT_KEY) { _set_error("key or '}' expected"); @@ -826,7 +834,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (expecting == DICT_EXPECT_KEY) { - if (tokenizer->is_token_literal() && tokenizer->get_token(1) == GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->is_token_literal() && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name //lua style identifier, easier to write ConstantNode *cn = alloc_node<ConstantNode>(); @@ -849,8 +857,8 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return NULL; expecting = DICT_EXPECT_COMMA; - if (key->type == GDParser::Node::TYPE_CONSTANT) { - Variant const &keyName = static_cast<const GDParser::ConstantNode *>(key)->value; + if (key->type == GDScriptParser::Node::TYPE_CONSTANT) { + Variant const &keyName = static_cast<const GDScriptParser::ConstantNode *>(key)->value; if (keys.has(keyName)) { _set_error("Duplicate key found in Dictionary literal"); @@ -870,7 +878,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expr = dict; - } else if (tokenizer->get_token() == GDTokenizer::TK_PERIOD && (tokenizer->is_token_literal(1) || tokenizer->get_token(1) == GDTokenizer::TK_CURSOR) && tokenizer->get_token(2) == GDTokenizer::TK_PARENTHESIS_OPEN) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && (tokenizer->is_token_literal(1) || tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR) && tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name // parent call @@ -907,7 +915,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool } if (!expr) { - ERR_EXPLAIN("GDParser bug, couldn't figure out what expression is.."); + ERR_EXPLAIN("GDScriptParser bug, couldn't figure out what expression is.."); ERR_FAIL_COND_V(!expr, NULL); } @@ -919,15 +927,15 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool //expressions can be indexed any number of times - if (tokenizer->get_token() == GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) { //indexing using "." - if (tokenizer->get_token(1) != GDTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) { + if (tokenizer->get_token(1) != GDScriptTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name _set_error("Expected identifier as member"); return NULL; - } else if (tokenizer->get_token(2) == GDTokenizer::TK_PARENTHESIS_OPEN) { + } else if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { //call!! OperatorNode *op = alloc_node<OperatorNode>(); op->op = OperatorNode::OP_CALL; @@ -935,10 +943,10 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool tokenizer->advance(); IdentifierNode *id = alloc_node<IdentifierNode>(); - if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_FUNC) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { //small hack so built in funcs don't obfuscate methods - id->name = GDFunctions::get_func_name(tokenizer->get_token_built_in_func()); + id->name = GDScriptFunctions::get_func_name(tokenizer->get_token_built_in_func()); tokenizer->advance(); } else { @@ -955,7 +963,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool op->arguments.push_back(id); // call func //get arguments tokenizer->advance(1); - if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { _make_completable_call(0); completion_node = op; } @@ -990,7 +998,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool expr = op; } - } else if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_OPEN) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) { //indexing using "[]" OperatorNode *op = alloc_node<OperatorNode>(); op->op = OperatorNode::OP_INDEX; @@ -1002,7 +1010,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return NULL; } - if (tokenizer->get_token() != GDTokenizer::TK_BRACKET_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_BRACKET_CLOSE) { _set_error("Expected ']'"); return NULL; } @@ -1022,7 +1030,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (parenthesis > 0) { //remove empty space (only allowed if inside parenthesis - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); } } @@ -1047,29 +1055,29 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool switch (tokenizer->get_token()) { //see operator - case GDTokenizer::TK_OP_IN: op = OperatorNode::OP_IN; break; - case GDTokenizer::TK_OP_EQUAL: op = OperatorNode::OP_EQUAL; break; - case GDTokenizer::TK_OP_NOT_EQUAL: op = OperatorNode::OP_NOT_EQUAL; break; - case GDTokenizer::TK_OP_LESS: op = OperatorNode::OP_LESS; break; - case GDTokenizer::TK_OP_LESS_EQUAL: op = OperatorNode::OP_LESS_EQUAL; break; - case GDTokenizer::TK_OP_GREATER: op = OperatorNode::OP_GREATER; break; - case GDTokenizer::TK_OP_GREATER_EQUAL: op = OperatorNode::OP_GREATER_EQUAL; break; - case GDTokenizer::TK_OP_AND: op = OperatorNode::OP_AND; break; - case GDTokenizer::TK_OP_OR: op = OperatorNode::OP_OR; break; - case GDTokenizer::TK_OP_ADD: op = OperatorNode::OP_ADD; break; - case GDTokenizer::TK_OP_SUB: op = OperatorNode::OP_SUB; break; - case GDTokenizer::TK_OP_MUL: op = OperatorNode::OP_MUL; break; - case GDTokenizer::TK_OP_DIV: op = OperatorNode::OP_DIV; break; - case GDTokenizer::TK_OP_MOD: + case GDScriptTokenizer::TK_OP_IN: op = OperatorNode::OP_IN; break; + case GDScriptTokenizer::TK_OP_EQUAL: op = OperatorNode::OP_EQUAL; break; + case GDScriptTokenizer::TK_OP_NOT_EQUAL: op = OperatorNode::OP_NOT_EQUAL; break; + case GDScriptTokenizer::TK_OP_LESS: op = OperatorNode::OP_LESS; break; + case GDScriptTokenizer::TK_OP_LESS_EQUAL: op = OperatorNode::OP_LESS_EQUAL; break; + case GDScriptTokenizer::TK_OP_GREATER: op = OperatorNode::OP_GREATER; break; + case GDScriptTokenizer::TK_OP_GREATER_EQUAL: op = OperatorNode::OP_GREATER_EQUAL; break; + case GDScriptTokenizer::TK_OP_AND: op = OperatorNode::OP_AND; break; + case GDScriptTokenizer::TK_OP_OR: op = OperatorNode::OP_OR; break; + case GDScriptTokenizer::TK_OP_ADD: op = OperatorNode::OP_ADD; break; + case GDScriptTokenizer::TK_OP_SUB: op = OperatorNode::OP_SUB; break; + case GDScriptTokenizer::TK_OP_MUL: op = OperatorNode::OP_MUL; break; + case GDScriptTokenizer::TK_OP_DIV: op = OperatorNode::OP_DIV; break; + case GDScriptTokenizer::TK_OP_MOD: op = OperatorNode::OP_MOD; break; - //case GDTokenizer::TK_OP_NEG: op=OperatorNode::OP_NEG ; break; - case GDTokenizer::TK_OP_SHIFT_LEFT: op = OperatorNode::OP_SHIFT_LEFT; break; - case GDTokenizer::TK_OP_SHIFT_RIGHT: op = OperatorNode::OP_SHIFT_RIGHT; break; - case GDTokenizer::TK_OP_ASSIGN: { + //case GDScriptTokenizer::TK_OP_NEG: op=OperatorNode::OP_NEG ; break; + case GDScriptTokenizer::TK_OP_SHIFT_LEFT: op = OperatorNode::OP_SHIFT_LEFT; break; + case GDScriptTokenizer::TK_OP_SHIFT_RIGHT: op = OperatorNode::OP_SHIFT_RIGHT; break; + case GDScriptTokenizer::TK_OP_ASSIGN: { _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN; - if (tokenizer->get_token(1) == GDTokenizer::TK_CURSOR) { + if (tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR) { //code complete assignment completion_type = COMPLETION_ASSIGN; completion_node = expr; @@ -1082,22 +1090,22 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool } } break; - case GDTokenizer::TK_OP_ASSIGN_ADD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD; break; - case GDTokenizer::TK_OP_ASSIGN_SUB: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB; break; - case GDTokenizer::TK_OP_ASSIGN_MUL: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL; break; - case GDTokenizer::TK_OP_ASSIGN_DIV: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_DIV; break; - case GDTokenizer::TK_OP_ASSIGN_MOD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MOD; break; - case GDTokenizer::TK_OP_ASSIGN_SHIFT_LEFT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_LEFT; break; - case GDTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_RIGHT; break; - case GDTokenizer::TK_OP_ASSIGN_BIT_AND: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_AND; break; - case GDTokenizer::TK_OP_ASSIGN_BIT_OR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_OR; break; - case GDTokenizer::TK_OP_ASSIGN_BIT_XOR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_XOR; break; - case GDTokenizer::TK_OP_BIT_AND: op = OperatorNode::OP_BIT_AND; break; - case GDTokenizer::TK_OP_BIT_OR: op = OperatorNode::OP_BIT_OR; break; - case GDTokenizer::TK_OP_BIT_XOR: op = OperatorNode::OP_BIT_XOR; break; - case GDTokenizer::TK_PR_IS: op = OperatorNode::OP_IS; break; - case GDTokenizer::TK_CF_IF: op = OperatorNode::OP_TERNARY_IF; break; - case GDTokenizer::TK_CF_ELSE: op = OperatorNode::OP_TERNARY_ELSE; break; + case GDScriptTokenizer::TK_OP_ASSIGN_ADD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD; break; + case GDScriptTokenizer::TK_OP_ASSIGN_SUB: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB; break; + case GDScriptTokenizer::TK_OP_ASSIGN_MUL: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL; break; + case GDScriptTokenizer::TK_OP_ASSIGN_DIV: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_DIV; break; + case GDScriptTokenizer::TK_OP_ASSIGN_MOD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MOD; break; + case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_LEFT; break; + case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_RIGHT; break; + case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_AND; break; + case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_OR; break; + case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_XOR; break; + case GDScriptTokenizer::TK_OP_BIT_AND: op = OperatorNode::OP_BIT_AND; break; + case GDScriptTokenizer::TK_OP_BIT_OR: op = OperatorNode::OP_BIT_OR; break; + case GDScriptTokenizer::TK_OP_BIT_XOR: op = OperatorNode::OP_BIT_XOR; break; + case GDScriptTokenizer::TK_PR_IS: op = OperatorNode::OP_IS; break; + case GDScriptTokenizer::TK_CF_IF: op = OperatorNode::OP_TERNARY_IF; break; + case GDScriptTokenizer::TK_CF_ELSE: op = OperatorNode::OP_TERNARY_ELSE; break; default: valid = false; break; } @@ -1205,7 +1213,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool case OperatorNode::OP_ASSIGN_BIT_XOR: priority = 15; break; default: { - _set_error("GDParser bug, invalid operator in expression: " + itos(expression[i].op)); + _set_error("GDScriptParser bug, invalid operator in expression: " + itos(expression[i].op)); return NULL; } } @@ -1351,7 +1359,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return expression[0].node; } -GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) { +GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to_const) { switch (p_node->type) { @@ -1448,7 +1456,7 @@ GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) { } else if (op->op == OperatorNode::OP_CALL) { //can reduce base type constructors - if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) { + if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDScriptFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) { //native type constructor or intrinsic function const Variant **vptr = NULL; @@ -1473,8 +1481,8 @@ GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) { v = Variant::construct(tn->vtype, vptr, ptrs.size(), ce); } else { - GDFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function; - GDFunctions::call(func, vptr, ptrs.size(), v, ce); + GDScriptFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function; + GDScriptFunctions::call(func, vptr, ptrs.size(), v, ce); } if (ce.error != Variant::CallError::CALL_OK) { @@ -1485,8 +1493,8 @@ GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) { errwhere = "'" + Variant::get_type_name(tn->vtype) + "'' constructor"; } else { - GDFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function; - errwhere = String("'") + GDFunctions::get_func_name(func) + "'' intrinsic function"; + GDScriptFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function; + errwhere = String("'") + GDScriptFunctions::get_func_name(func) + "'' intrinsic function"; } switch (ce.error) { @@ -1736,7 +1744,7 @@ GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) { } } -GDParser::Node *GDParser::_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const, bool p_allow_assign) { +GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const, bool p_allow_assign) { Node *expr = _parse_expression(p_parent, p_static, p_allow_assign, p_reduce_const); if (!expr || error_set) @@ -1747,58 +1755,58 @@ GDParser::Node *GDParser::_parse_and_reduce_expression(Node *p_parent, bool p_st return expr; } -bool GDParser::_recover_from_completion() { +bool GDScriptParser::_recover_from_completion() { if (!completion_found) { return false; //can't recover if no completion } //skip stuff until newline - while (tokenizer->get_token() != GDTokenizer::TK_NEWLINE && tokenizer->get_token() != GDTokenizer::TK_EOF && tokenizer->get_token() != GDTokenizer::TK_ERROR) { + while (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token() != GDScriptTokenizer::TK_EOF && tokenizer->get_token() != GDScriptTokenizer::TK_ERROR) { tokenizer->advance(); } completion_found = false; error_set = false; - if (tokenizer->get_token() == GDTokenizer::TK_ERROR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_ERROR) { error_set = true; } return true; } -GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { +GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) { PatternNode *pattern = alloc_node<PatternNode>(); - GDTokenizer::Token token = tokenizer->get_token(); + GDScriptTokenizer::Token token = tokenizer->get_token(); if (error_set) return NULL; - if (token == GDTokenizer::TK_EOF) { + if (token == GDScriptTokenizer::TK_EOF) { return NULL; } switch (token) { // array - case GDTokenizer::TK_BRACKET_OPEN: { + case GDScriptTokenizer::TK_BRACKET_OPEN: { tokenizer->advance(); - pattern->pt_type = GDParser::PatternNode::PT_ARRAY; + pattern->pt_type = GDScriptParser::PatternNode::PT_ARRAY; while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(); break; } - if (tokenizer->get_token() == GDTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) { // match everything tokenizer->advance(2); PatternNode *sub_pattern = alloc_node<PatternNode>(); - sub_pattern->pt_type = GDParser::PatternNode::PT_IGNORE_REST; + sub_pattern->pt_type = GDScriptParser::PatternNode::PT_IGNORE_REST; pattern->array.push_back(sub_pattern); - if (tokenizer->get_token() == GDTokenizer::TK_COMMA && tokenizer->get_token(1) == GDTokenizer::TK_BRACKET_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA && tokenizer->get_token(1) == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(2); break; - } else if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(1); break; } else { @@ -1814,10 +1822,10 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { pattern->array.push_back(sub_pattern); - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); continue; - } else if (tokenizer->get_token() == GDTokenizer::TK_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(); break; } else { @@ -1827,33 +1835,33 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { } } break; // bind - case GDTokenizer::TK_PR_VAR: { + case GDScriptTokenizer::TK_PR_VAR: { tokenizer->advance(); - pattern->pt_type = GDParser::PatternNode::PT_BIND; + pattern->pt_type = GDScriptParser::PatternNode::PT_BIND; pattern->bind = tokenizer->get_token_identifier(); tokenizer->advance(); } break; // dictionary - case GDTokenizer::TK_CURLY_BRACKET_OPEN: { + case GDScriptTokenizer::TK_CURLY_BRACKET_OPEN: { tokenizer->advance(); - pattern->pt_type = GDParser::PatternNode::PT_DICTIONARY; + pattern->pt_type = GDScriptParser::PatternNode::PT_DICTIONARY; while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(); break; } - if (tokenizer->get_token() == GDTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) { // match everything tokenizer->advance(2); PatternNode *sub_pattern = alloc_node<PatternNode>(); sub_pattern->pt_type = PatternNode::PT_IGNORE_REST; pattern->array.push_back(sub_pattern); - if (tokenizer->get_token() == GDTokenizer::TK_COMMA && tokenizer->get_token(1) == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA && tokenizer->get_token(1) == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(2); break; - } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(1); break; } else { @@ -1868,12 +1876,12 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { return NULL; } - if (key->type != GDParser::Node::TYPE_CONSTANT) { + if (key->type != GDScriptParser::Node::TYPE_CONSTANT) { _set_error("Not a constant expression as key"); return NULL; } - if (tokenizer->get_token() == GDTokenizer::TK_COLON) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { tokenizer->advance(); PatternNode *value = _parse_pattern(p_static); @@ -1887,10 +1895,10 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { pattern->dictionary.insert(static_cast<ConstantNode *>(key), NULL); } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); continue; - } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(); break; } else { @@ -1899,7 +1907,7 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { } } } break; - case GDTokenizer::TK_WILDCARD: { + case GDScriptTokenizer::TK_WILDCARD: { tokenizer->advance(); pattern->pt_type = PatternNode::PT_WILDCARD; } break; @@ -1943,15 +1951,15 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { return pattern; } -void GDParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static) { +void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static) { int indent_level = tab_level.back()->get(); while (true) { - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE && _parse_newline()) + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) ; - // GDTokenizer::Token token = tokenizer->get_token(); + // GDScriptTokenizer::Token token = tokenizer->get_token(); if (error_set) return; @@ -1970,7 +1978,7 @@ void GDParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode return; } - while (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); branch->patterns.push_back(_parse_pattern(p_static)); if (!branch->patterns[branch->patterns.size() - 1]) { @@ -1996,13 +2004,13 @@ void GDParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode } } -void GDParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) { +void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) { switch (p_pattern->pt_type) { case PatternNode::PT_CONSTANT: { // typecheck BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>(); - typeof_node->function = GDFunctions::TYPE_OF; + typeof_node->function = GDScriptFunctions::TYPE_OF; OperatorNode *typeof_match_value = alloc_node<OperatorNode>(); typeof_match_value->op = OperatorNode::OP_CALL; @@ -2057,7 +2065,7 @@ void GDParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, { // typecheck BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>(); - typeof_node->function = GDFunctions::TYPE_OF; + typeof_node->function = GDScriptFunctions::TYPE_OF; OperatorNode *typeof_match_value = alloc_node<OperatorNode>(); typeof_match_value->op = OperatorNode::OP_CALL; @@ -2136,7 +2144,7 @@ void GDParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, { // typecheck BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>(); - typeof_node->function = GDFunctions::TYPE_OF; + typeof_node->function = GDScriptFunctions::TYPE_OF; OperatorNode *typeof_match_value = alloc_node<OperatorNode>(); typeof_match_value->op = OperatorNode::OP_CALL; @@ -2234,7 +2242,7 @@ void GDParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, } } -void GDParser::_transform_match_statment(BlockNode *p_block, MatchNode *p_match_statement) { +void GDScriptParser::_transform_match_statment(BlockNode *p_block, MatchNode *p_match_statement) { IdentifierNode *id = alloc_node<IdentifierNode>(); id->name = "#match_value"; @@ -2298,7 +2306,7 @@ void GDParser::_transform_match_statment(BlockNode *p_block, MatchNode *p_match_ } } -void GDParser::_parse_block(BlockNode *p_block, bool p_static) { +void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { int indent_level = tab_level.back()->get(); @@ -2321,7 +2329,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } is_first_line = false; - GDTokenizer::Token token = tokenizer->get_token(); + GDScriptTokenizer::Token token = tokenizer->get_token(); if (error_set) return; @@ -2340,15 +2348,15 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { switch (token) { - case GDTokenizer::TK_EOF: + case GDScriptTokenizer::TK_EOF: p_block->end_line = tokenizer->get_token_line(); - case GDTokenizer::TK_ERROR: { + case GDScriptTokenizer::TK_ERROR: { return; //go back //end of file! } break; - case GDTokenizer::TK_NEWLINE: { + case GDScriptTokenizer::TK_NEWLINE: { if (!_parse_newline()) { if (!error_set) { @@ -2363,19 +2371,19 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { p_block->statements.push_back(nl); } break; - case GDTokenizer::TK_CF_PASS: { - if (tokenizer->get_token(1) != GDTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDTokenizer::TK_EOF) { + case GDScriptTokenizer::TK_CF_PASS: { + if (tokenizer->get_token(1) != GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF) { _set_error("Expected ';' or <NewLine>."); return; } tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_SEMICOLON) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) { // Ignore semicolon after 'pass' tokenizer->advance(); } } break; - case GDTokenizer::TK_PR_VAR: { + case GDScriptTokenizer::TK_PR_VAR: { //variale declaration and (eventual) initialization tokenizer->advance(); @@ -2414,7 +2422,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { Node *assigned = NULL; - if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { tokenizer->advance(); Node *subexpr = _parse_and_reduce_expression(p_block, p_static); @@ -2452,7 +2460,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; - case GDTokenizer::TK_CF_IF: { + case GDScriptTokenizer::TK_CF_IF: { tokenizer->advance(); @@ -2491,7 +2499,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { while (true) { - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE && _parse_newline()) + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) ; if (tab_level.back()->get() < indent_level) { //not at current indent level @@ -2499,7 +2507,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; } - if (tokenizer->get_token() == GDTokenizer::TK_CF_ELIF) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELIF) { if (tab_level.back()->get() > indent_level) { @@ -2545,7 +2553,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { if (error_set) return; - } else if (tokenizer->get_token() == GDTokenizer::TK_CF_ELSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELSE) { if (tab_level.back()->get() > indent_level) { _set_error("Invalid indent"); @@ -2575,7 +2583,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; - case GDTokenizer::TK_CF_WHILE: { + case GDScriptTokenizer::TK_CF_WHILE: { tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block, p_static); @@ -2608,7 +2616,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; p_block->statements.push_back(cf_while); } break; - case GDTokenizer::TK_CF_FOR: { + case GDScriptTokenizer::TK_CF_FOR: { tokenizer->advance(); @@ -2622,7 +2630,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_OP_IN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_IN) { _set_error("'in' expected after identifier"); return; } @@ -2640,7 +2648,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { if (container->type == Node::TYPE_OPERATOR) { OperatorNode *op = static_cast<OperatorNode *>(container); - if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode *>(op->arguments[0])->function == GDFunctions::GEN_RANGE) { + if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode *>(op->arguments[0])->function == GDScriptFunctions::GEN_RANGE) { //iterating a range, so see if range() can be optimized without allocating memory, by replacing it by vectors (which can work as iterable too!) Vector<Node *> args; @@ -2726,7 +2734,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; p_block->statements.push_back(cf_for); } break; - case GDTokenizer::TK_CF_CONTINUE: { + case GDScriptTokenizer::TK_CF_CONTINUE: { tokenizer->advance(); ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>(); @@ -2737,7 +2745,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; } } break; - case GDTokenizer::TK_CF_BREAK: { + case GDScriptTokenizer::TK_CF_BREAK: { tokenizer->advance(); ControlFlowNode *cf_break = alloc_node<ControlFlowNode>(); @@ -2748,13 +2756,13 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; } } break; - case GDTokenizer::TK_CF_RETURN: { + case GDScriptTokenizer::TK_CF_RETURN: { tokenizer->advance(); ControlFlowNode *cf_return = alloc_node<ControlFlowNode>(); cf_return->cf_type = ControlFlowNode::CF_RETURN; - if (tokenizer->get_token() == GDTokenizer::TK_SEMICOLON || tokenizer->get_token() == GDTokenizer::TK_NEWLINE || tokenizer->get_token() == GDTokenizer::TK_EOF) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON || tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE || tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { //expect end of statement p_block->statements.push_back(cf_return); if (!_end_statement()) { @@ -2778,7 +2786,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; - case GDTokenizer::TK_CF_MATCH: { + case GDScriptTokenizer::TK_CF_MATCH: { tokenizer->advance(); @@ -2818,7 +2826,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { _end_statement(); } break; - case GDTokenizer::TK_PR_ASSERT: { + case GDScriptTokenizer::TK_PR_ASSERT: { tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block, p_static); @@ -2837,7 +2845,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { return; } } break; - case GDTokenizer::TK_PR_BREAKPOINT: { + case GDScriptTokenizer::TK_PR_BREAKPOINT: { tokenizer->advance(); BreakpointNode *bn = alloc_node<BreakpointNode>(); @@ -2865,9 +2873,9 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } break; /* - case GDTokenizer::TK_CF_LOCAL: { + case GDScriptTokenizer::TK_CF_LOCAL: { - if (tokenizer->get_token(1)!=GDTokenizer::TK_SEMICOLON && tokenizer->get_token(1)!=GDTokenizer::TK_NEWLINE ) { + if (tokenizer->get_token(1)!=GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1)!=GDScriptTokenizer::TK_NEWLINE ) { _set_error("Expected ';' or <NewLine>."); } @@ -2878,9 +2886,9 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { } } -bool GDParser::_parse_newline() { +bool GDScriptParser::_parse_newline() { - if (tokenizer->get_token(1) != GDTokenizer::TK_EOF && tokenizer->get_token(1) != GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) { int indent = tokenizer->get_token_line_indent(); int current_indent = tab_level.back()->get(); @@ -2919,7 +2927,7 @@ bool GDParser::_parse_newline() { return true; } -void GDParser::_parse_extends(ClassNode *p_class) { +void GDScriptParser::_parse_extends(ClassNode *p_class) { if (p_class->extends_used) { @@ -2937,14 +2945,14 @@ void GDParser::_parse_extends(ClassNode *p_class) { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token_type() == Variant::OBJECT) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token_type() == Variant::OBJECT) { p_class->extends_class.push_back(Variant::get_type_name(Variant::OBJECT)); tokenizer->advance(); return; } // see if inheritance happens from a file - if (tokenizer->get_token() == GDTokenizer::TK_CONSTANT) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) { Variant constant = tokenizer->get_token_constant(); if (constant.get_type() != Variant::STRING) { @@ -2956,14 +2964,14 @@ void GDParser::_parse_extends(ClassNode *p_class) { p_class->extends_file = constant; tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PERIOD) { return; } else tokenizer->advance(); } while (true) { - if (tokenizer->get_token() != GDTokenizer::TK_IDENTIFIER) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) { _set_error("Invalid 'extends' syntax, expected string constant (path) and/or identifier (parent class)."); return; @@ -2973,18 +2981,18 @@ void GDParser::_parse_extends(ClassNode *p_class) { p_class->extends_class.push_back(identifier); tokenizer->advance(1); - if (tokenizer->get_token() != GDTokenizer::TK_PERIOD) + if (tokenizer->get_token() != GDScriptTokenizer::TK_PERIOD) return; } } -void GDParser::_parse_class(ClassNode *p_class) { +void GDScriptParser::_parse_class(ClassNode *p_class) { int indent_level = tab_level.back()->get(); while (true) { - GDTokenizer::Token token = tokenizer->get_token(); + GDScriptTokenizer::Token token = tokenizer->get_token(); if (error_set) return; @@ -2995,13 +3003,13 @@ void GDParser::_parse_class(ClassNode *p_class) { switch (token) { - case GDTokenizer::TK_EOF: + case GDScriptTokenizer::TK_EOF: p_class->end_line = tokenizer->get_token_line(); - case GDTokenizer::TK_ERROR: { + case GDScriptTokenizer::TK_ERROR: { return; //go back //end of file! } break; - case GDTokenizer::TK_NEWLINE: { + case GDScriptTokenizer::TK_NEWLINE: { if (!_parse_newline()) { if (!error_set) { p_class->end_line = tokenizer->get_token_line(); @@ -3009,7 +3017,7 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } } break; - case GDTokenizer::TK_PR_EXTENDS: { + case GDScriptTokenizer::TK_PR_EXTENDS: { _parse_extends(p_class); if (error_set) @@ -3020,7 +3028,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } break; - case GDTokenizer::TK_PR_TOOL: { + case GDScriptTokenizer::TK_PR_TOOL: { if (p_class->tool) { @@ -3032,13 +3040,13 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } break; - case GDTokenizer::TK_PR_CLASS: { + case GDScriptTokenizer::TK_PR_CLASS: { //class inside class :D StringName name; StringName extends; - if (tokenizer->get_token(1) != GDTokenizer::TK_IDENTIFIER) { + if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) { _set_error("'class' syntax: 'class <Name>:' or 'class <Name> extends <BaseClass>:'"); return; @@ -3056,7 +3064,7 @@ void GDParser::_parse_class(ClassNode *p_class) { p_class->subclasses.push_back(newclass); - if (tokenizer->get_token() == GDTokenizer::TK_PR_EXTENDS) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_EXTENDS) { _parse_extends(newclass); if (error_set) @@ -3074,26 +3082,26 @@ void GDParser::_parse_class(ClassNode *p_class) { } break; /* this is for functions.... - case GDTokenizer::TK_CF_PASS: { + case GDScriptTokenizer::TK_CF_PASS: { tokenizer->advance(1); } break; */ - case GDTokenizer::TK_PR_STATIC: { + case GDScriptTokenizer::TK_PR_STATIC: { tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PR_FUNCTION) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { _set_error("Expected 'func'."); return; } }; //fallthrough to function - case GDTokenizer::TK_PR_FUNCTION: { + case GDScriptTokenizer::TK_PR_FUNCTION: { bool _static = false; pending_newline = -1; - if (tokenizer->get_token(-1) == GDTokenizer::TK_PR_STATIC) { + if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_STATIC) { _static = true; } @@ -3121,7 +3129,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { _set_error("Expected '(' after identifier (syntax: 'func <identifier>([arguments]):' )."); return; @@ -3134,17 +3142,17 @@ void GDParser::_parse_class(ClassNode *p_class) { int fnline = tokenizer->get_token_line(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { //has arguments bool defaulting = false; while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); continue; } - if (tokenizer->get_token() == GDTokenizer::TK_PR_VAR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_VAR) { tokenizer->advance(); //var before the identifier is allowed } @@ -3160,7 +3168,7 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); - if (defaulting && tokenizer->get_token() != GDTokenizer::TK_OP_ASSIGN) { + if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) { _set_error("Default parameter expected."); return; @@ -3168,7 +3176,7 @@ void GDParser::_parse_class(ClassNode *p_class) { //tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { defaulting = true; tokenizer->advance(1); Node *defval = _parse_and_reduce_expression(p_class, _static); @@ -3192,14 +3200,14 @@ void GDParser::_parse_class(ClassNode *p_class) { default_values.push_back(on); } - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); continue; - } else if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ',' or ')'."); return; @@ -3226,14 +3234,14 @@ void GDParser::_parse_class(ClassNode *p_class) { id->name = "_init"; cparent->arguments.push_back(id); - if (tokenizer->get_token() == GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) { tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { _set_error("expected '(' for parent constructor arguments."); } tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { //has arguments parenthesis++; while (true) { @@ -3241,10 +3249,10 @@ void GDParser::_parse_class(ClassNode *p_class) { Node *arg = _parse_and_reduce_expression(p_class, _static); cparent->arguments.push_back(arg); - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); continue; - } else if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ',' or ')'."); return; @@ -3259,7 +3267,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } else { - if (tokenizer->get_token() == GDTokenizer::TK_PERIOD) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) { _set_error("Parent constructor call found for a class without inheritance."); return; @@ -3296,7 +3304,7 @@ void GDParser::_parse_class(ClassNode *p_class) { //arguments } break; - case GDTokenizer::TK_PR_SIGNAL: { + case GDScriptTokenizer::TK_PR_SIGNAL: { tokenizer->advance(); if (!tokenizer->is_token_literal()) { @@ -3308,15 +3316,15 @@ void GDParser::_parse_class(ClassNode *p_class) { sig.name = tokenizer->get_token_identifier(); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { tokenizer->advance(); while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); continue; } - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); break; } @@ -3329,13 +3337,13 @@ void GDParser::_parse_class(ClassNode *p_class) { sig.arguments.push_back(tokenizer->get_token_identifier()); tokenizer->advance(); - while (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); - } else if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ',' or ')' after signal parameter identifier."); return; } @@ -3349,14 +3357,14 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } } break; - case GDTokenizer::TK_PR_EXPORT: { + case GDScriptTokenizer::TK_PR_EXPORT: { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_OPEN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_TYPE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) { Variant::Type type = tokenizer->get_token_type(); if (type == Variant::NIL) { @@ -3369,17 +3377,17 @@ void GDParser::_parse_class(ClassNode *p_class) { String hint_prefix = ""; - if (type == Variant::ARRAY && tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (type == Variant::ARRAY && tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); - while (tokenizer->get_token() == GDTokenizer::TK_BUILT_IN_TYPE) { + while (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) { type = tokenizer->get_token_type(); tokenizer->advance(); if (type == Variant::ARRAY) { hint_prefix += itos(Variant::ARRAY) + ":"; - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); } } else { @@ -3389,7 +3397,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { // hint expected next! tokenizer->advance(); @@ -3397,15 +3405,15 @@ void GDParser::_parse_class(ClassNode *p_class) { case Variant::INT: { - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") { //current_export.hint=PROPERTY_HINT_ALL_FLAGS; tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; } - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { _set_error("Expected ')' or ',' in bit flags hint."); return; } @@ -3416,7 +3424,7 @@ void GDParser::_parse_class(ClassNode *p_class) { bool first = true; while (true) { - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { current_export = PropertyInfo(); _set_error("Expected a string constant in named bit flags hint."); return; @@ -3431,10 +3439,10 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint_string += c.xml_escape(); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); _set_error("Expected ')' or ',' in named bit flags hint."); return; @@ -3445,13 +3453,13 @@ void GDParser::_parse_class(ClassNode *p_class) { break; } - if (tokenizer->get_token() == GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) { //enumeration current_export.hint = PROPERTY_HINT_ENUM; bool first = true; while (true) { - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { current_export = PropertyInfo(); _set_error("Expected a string constant in enumeration hint."); @@ -3467,10 +3475,10 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint_string += c.xml_escape(); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); _set_error("Expected ')' or ',' in enumeration hint."); return; @@ -3485,10 +3493,10 @@ void GDParser::_parse_class(ClassNode *p_class) { }; //fallthrough to use the same case Variant::REAL: { - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") { current_export.hint = PROPERTY_HINT_EXP_EASING; tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in hint."); return; } @@ -3496,14 +3504,14 @@ void GDParser::_parse_class(ClassNode *p_class) { } // range - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") { current_export.hint = PROPERTY_HINT_EXP_RANGE; tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - else if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { _set_error("Expected ')' or ',' in exponential range hint."); return; } @@ -3513,11 +3521,11 @@ void GDParser::_parse_class(ClassNode *p_class) { float sign = 1.0; - if (tokenizer->get_token() == GDTokenizer::TK_OP_SUB) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) { sign = -1; tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { current_export = PropertyInfo(); _set_error("Expected a range in numeric hint."); @@ -3527,12 +3535,12 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint_string = rtos(sign * double(tokenizer->get_token_constant())); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { current_export.hint_string = "0," + current_export.hint_string; break; } - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); _set_error("Expected ',' or ')' in numeric range hint."); @@ -3542,12 +3550,12 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); sign = 1.0; - if (tokenizer->get_token() == GDTokenizer::TK_OP_SUB) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) { sign = -1; tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { current_export = PropertyInfo(); _set_error("Expected a number as upper bound in numeric range hint."); @@ -3557,10 +3565,10 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant())); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); _set_error("Expected ',' or ')' in numeric range hint."); @@ -3569,12 +3577,12 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); sign = 1.0; - if (tokenizer->get_token() == GDTokenizer::TK_OP_SUB) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) { sign = -1; tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { current_export = PropertyInfo(); _set_error("Expected a number as step in numeric range hint."); @@ -3587,13 +3595,13 @@ void GDParser::_parse_class(ClassNode *p_class) { } break; case Variant::STRING: { - if (tokenizer->get_token() == GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) { //enumeration current_export.hint = PROPERTY_HINT_ENUM; bool first = true; while (true) { - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { current_export = PropertyInfo(); _set_error("Expected a string constant in enumeration hint."); @@ -3608,10 +3616,10 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint_string += c.xml_escape(); tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); _set_error("Expected ')' or ',' in enumeration hint."); return; @@ -3622,17 +3630,17 @@ void GDParser::_parse_class(ClassNode *p_class) { break; } - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) current_export.hint = PROPERTY_HINT_DIR; - else if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) { _set_error("Expected 'GLOBAL' after comma in directory hint."); return; } @@ -3643,7 +3651,7 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_GLOBAL_DIR; tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in hint."); return; } @@ -3654,16 +3662,16 @@ void GDParser::_parse_class(ClassNode *p_class) { break; } - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") { current_export.hint = PROPERTY_HINT_FILE; tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") { if (!p_class->tool) { _set_error("Global filesystem hints may only be used in tool scripts."); @@ -3672,9 +3680,9 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_GLOBAL_FILE; tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) break; - else if (tokenizer->get_token() == GDTokenizer::TK_COMMA) + else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) tokenizer->advance(); else { _set_error("Expected ')' or ',' in hint."); @@ -3682,7 +3690,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } - if (tokenizer->get_token() != GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE) _set_error("Expected string constant with filter"); @@ -3694,18 +3702,18 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in hint."); return; } break; } - if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") { + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") { current_export.hint = PROPERTY_HINT_MULTILINE_TEXT; tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' in hint."); return; } @@ -3714,7 +3722,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } break; case Variant::COLOR: { - if (tokenizer->get_token() != GDTokenizer::TK_IDENTIFIER) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) { current_export = PropertyInfo(); _set_error("Color type hint expects RGB or RGBA as hints"); @@ -3750,7 +3758,7 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_NONE; } - } else if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER) { String identifier = tokenizer->get_token_identifier(); if (!ClassDB::is_parent_class(identifier, "Resource")) { @@ -3768,7 +3776,7 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_PARENTHESIS_CLOSE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { current_export = PropertyInfo(); _set_error("Expected ')' or ',' after export hint."); @@ -3778,7 +3786,7 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR && tokenizer->get_token() != GDTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDTokenizer::TK_PR_SYNC) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC) { current_export = PropertyInfo(); _set_error("Expected 'var', 'onready', 'remote', 'master', 'slave' or 'sync'."); @@ -3787,29 +3795,29 @@ void GDParser::_parse_class(ClassNode *p_class) { continue; } break; - case GDTokenizer::TK_PR_ONREADY: { + case GDScriptTokenizer::TK_PR_ONREADY: { //may be fallthrough from export, ignore if so tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) { _set_error("Expected 'var'."); return; } continue; } break; - case GDTokenizer::TK_PR_REMOTE: { + case GDScriptTokenizer::TK_PR_REMOTE: { //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) { _set_error("Expected 'var'."); return; } } else { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR && tokenizer->get_token() != GDTokenizer::TK_PR_FUNCTION) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { _set_error("Expected 'var' or 'func'."); return; } @@ -3818,18 +3826,18 @@ void GDParser::_parse_class(ClassNode *p_class) { continue; } break; - case GDTokenizer::TK_PR_MASTER: { + case GDScriptTokenizer::TK_PR_MASTER: { //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) { _set_error("Expected 'var'."); return; } } else { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR && tokenizer->get_token() != GDTokenizer::TK_PR_FUNCTION) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { _set_error("Expected 'var' or 'func'."); return; } @@ -3838,18 +3846,18 @@ void GDParser::_parse_class(ClassNode *p_class) { rpc_mode = ScriptInstance::RPC_MODE_MASTER; continue; } break; - case GDTokenizer::TK_PR_SLAVE: { + case GDScriptTokenizer::TK_PR_SLAVE: { //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) { _set_error("Expected 'var'."); return; } } else { - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR && tokenizer->get_token() != GDTokenizer::TK_PR_FUNCTION) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { _set_error("Expected 'var' or 'func'."); return; } @@ -3858,11 +3866,11 @@ void GDParser::_parse_class(ClassNode *p_class) { rpc_mode = ScriptInstance::RPC_MODE_SLAVE; continue; } break; - case GDTokenizer::TK_PR_SYNC: { + case GDScriptTokenizer::TK_PR_SYNC: { //may be fallthrough from export, ignore if so tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_PR_VAR && tokenizer->get_token() != GDTokenizer::TK_PR_FUNCTION) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { if (current_export.type) _set_error("Expected 'var'."); else @@ -3873,17 +3881,17 @@ void GDParser::_parse_class(ClassNode *p_class) { rpc_mode = ScriptInstance::RPC_MODE_SYNC; continue; } break; - case GDTokenizer::TK_PR_VAR: { + case GDScriptTokenizer::TK_PR_VAR: { //variale declaration and (eventual) initialization ClassNode::Member member; - bool autoexport = tokenizer->get_token(-1) == GDTokenizer::TK_PR_EXPORT; + bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT; if (current_export.type != Variant::NIL) { member._export = current_export; current_export = PropertyInfo(); } - bool onready = tokenizer->get_token(-1) == GDTokenizer::TK_PR_ONREADY; + bool onready = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_ONREADY; tokenizer->advance(); if (!tokenizer->is_token_literal(0, true)) { @@ -3902,7 +3910,7 @@ void GDParser::_parse_class(ClassNode *p_class) { rpc_mode = ScriptInstance::RPC_MODE_DISABLED; - if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { #ifdef DEBUG_ENABLED int line = tokenizer->get_token_line(); @@ -4010,11 +4018,11 @@ void GDParser::_parse_class(ClassNode *p_class) { } } - if (tokenizer->get_token() == GDTokenizer::TK_PR_SETGET) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_SETGET) { tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { //just comma means using only getter if (!tokenizer->is_token_literal()) { _set_error("Expected identifier for setter function after 'setget'."); @@ -4025,7 +4033,7 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { //there is a getter tokenizer->advance(); @@ -4045,7 +4053,7 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } } break; - case GDTokenizer::TK_PR_CONST: { + case GDScriptTokenizer::TK_PR_CONST: { //variale declaration and (eventual) initialization ClassNode::Constant constant; @@ -4060,7 +4068,7 @@ void GDParser::_parse_class(ClassNode *p_class) { constant.identifier = tokenizer->get_token_literal(); tokenizer->advance(); - if (tokenizer->get_token() != GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) { _set_error("Constant expects assignment."); return; } @@ -4088,7 +4096,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } break; - case GDTokenizer::TK_PR_ENUM: { + case GDScriptTokenizer::TK_PR_ENUM: { //mutiple constant declarations.. int last_assign = -1; // Incremented by 1 right before the assingment. @@ -4100,26 +4108,26 @@ void GDParser::_parse_class(ClassNode *p_class) { enum_name = tokenizer->get_token_literal(); tokenizer->advance(); } - if (tokenizer->get_token() != GDTokenizer::TK_CURLY_BRACKET_OPEN) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_CURLY_BRACKET_OPEN) { _set_error("Expected '{' in enum declaration"); return; } tokenizer->advance(); while (true) { - if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); // Ignore newlines - } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(); break; // End of enum } else if (!tokenizer->is_token_literal(0, true)) { - if (tokenizer->get_token() == GDTokenizer::TK_EOF) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { _set_error("Unexpected end of file."); } else { - _set_error(String("Unexpected ") + GDTokenizer::get_token_name(tokenizer->get_token()) + ", expected identifier"); + _set_error(String("Unexpected ") + GDScriptTokenizer::get_token_name(tokenizer->get_token()) + ", expected identifier"); } return; @@ -4130,7 +4138,7 @@ void GDParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); - if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { tokenizer->advance(); Node *subexpr = _parse_and_reduce_expression(p_class, true, true); @@ -4162,7 +4170,7 @@ void GDParser::_parse_class(ClassNode *p_class) { constant.expression = cn; } - if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); } @@ -4191,7 +4199,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } break; - case GDTokenizer::TK_CONSTANT: { + case GDScriptTokenizer::TK_CONSTANT: { if (tokenizer->get_token_constant().get_type() == Variant::STRING) { tokenizer->advance(); // Ignore @@ -4211,7 +4219,7 @@ void GDParser::_parse_class(ClassNode *p_class) { } } -void GDParser::_set_error(const String &p_error, int p_line, int p_column) { +void GDScriptParser::_set_error(const String &p_error, int p_line, int p_column) { if (error_set) return; //allow no further errors @@ -4222,21 +4230,21 @@ void GDParser::_set_error(const String &p_error, int p_line, int p_column) { error_set = true; } -String GDParser::get_error() const { +String GDScriptParser::get_error() const { return error; } -int GDParser::get_error_line() const { +int GDScriptParser::get_error_line() const { return error_line; } -int GDParser::get_error_column() const { +int GDScriptParser::get_error_column() const { return error_column; } -Error GDParser::_parse(const String &p_base_path) { +Error GDScriptParser::_parse(const String &p_base_path) { base_path = p_base_path; @@ -4252,7 +4260,7 @@ Error GDParser::_parse(const String &p_base_path) { _parse_class(main_class); - if (tokenizer->get_token() == GDTokenizer::TK_ERROR) { + if (tokenizer->get_token() == GDScriptTokenizer::TK_ERROR) { error_set = false; _set_error("Parse Error: " + tokenizer->get_token_error()); } @@ -4264,7 +4272,7 @@ Error GDParser::_parse(const String &p_base_path) { return OK; } -Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) { +Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) { for_completion = false; validating = false; @@ -4279,7 +4287,7 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String & current_function = NULL; self_path = p_self_path; - GDTokenizerBuffer *tb = memnew(GDTokenizerBuffer); + GDScriptTokenizerBuffer *tb = memnew(GDScriptTokenizerBuffer); tb->set_code_buffer(p_bytecode); tokenizer = tb; Error ret = _parse(p_base_path); @@ -4288,7 +4296,7 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String & return ret; } -Error GDParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion) { +Error GDScriptParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion) { completion_type = COMPLETION_NONE; completion_node = NULL; @@ -4302,7 +4310,7 @@ Error GDParser::parse(const String &p_code, const String &p_base_path, bool p_ju current_function = NULL; self_path = p_self_path; - GDTokenizerText *tt = memnew(GDTokenizerText); + GDScriptTokenizerText *tt = memnew(GDScriptTokenizerText); tt->set_code(p_code); validating = p_just_validate; @@ -4314,17 +4322,17 @@ Error GDParser::parse(const String &p_code, const String &p_base_path, bool p_ju return ret; } -bool GDParser::is_tool_script() const { +bool GDScriptParser::is_tool_script() const { return (head && head->type == Node::TYPE_CLASS && static_cast<const ClassNode *>(head)->tool); } -const GDParser::Node *GDParser::get_parse_tree() const { +const GDScriptParser::Node *GDScriptParser::get_parse_tree() const { return head; } -void GDParser::clear() { +void GDScriptParser::clear() { while (list) { @@ -4362,57 +4370,57 @@ void GDParser::clear() { error = ""; } -GDParser::CompletionType GDParser::get_completion_type() { +GDScriptParser::CompletionType GDScriptParser::get_completion_type() { return completion_type; } -StringName GDParser::get_completion_cursor() { +StringName GDScriptParser::get_completion_cursor() { return completion_cursor; } -int GDParser::get_completion_line() { +int GDScriptParser::get_completion_line() { return completion_line; } -Variant::Type GDParser::get_completion_built_in_constant() { +Variant::Type GDScriptParser::get_completion_built_in_constant() { return completion_built_in_constant; } -GDParser::Node *GDParser::get_completion_node() { +GDScriptParser::Node *GDScriptParser::get_completion_node() { return completion_node; } -GDParser::BlockNode *GDParser::get_completion_block() { +GDScriptParser::BlockNode *GDScriptParser::get_completion_block() { return completion_block; } -GDParser::ClassNode *GDParser::get_completion_class() { +GDScriptParser::ClassNode *GDScriptParser::get_completion_class() { return completion_class; } -GDParser::FunctionNode *GDParser::get_completion_function() { +GDScriptParser::FunctionNode *GDScriptParser::get_completion_function() { return completion_function; } -int GDParser::get_completion_argument_index() { +int GDScriptParser::get_completion_argument_index() { return completion_argument; } -int GDParser::get_completion_identifier_is_function() { +int GDScriptParser::get_completion_identifier_is_function() { return completion_ident_is_call; } -GDParser::GDParser() { +GDScriptParser::GDScriptParser() { head = NULL; list = NULL; @@ -4421,7 +4429,7 @@ GDParser::GDParser() { clear(); } -GDParser::~GDParser() { +GDScriptParser::~GDScriptParser() { clear(); } diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gdscript_parser.h index 7e88fd9746..3c9c5ea02c 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_parser.h */ +/* gdscript_parser.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,16 +27,16 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_PARSER_H -#define GD_PARSER_H +#ifndef GDSCRIPT_PARSER_H +#define GDSCRIPT_PARSER_H -#include "gd_functions.h" -#include "gd_tokenizer.h" +#include "gdscript_functions.h" +#include "gdscript_tokenizer.h" #include "map.h" #include "object.h" #include "script_language.h" -class GDParser { +class GDScriptParser { public: struct Node { @@ -166,7 +166,7 @@ public: TypeNode() { type = TYPE_TYPE; } }; struct BuiltInFunctionNode : public Node { - GDFunctions::Function function; + GDScriptFunctions::Function function; BuiltInFunctionNode() { type = TYPE_BUILT_IN_FUNCTION; } }; @@ -448,7 +448,7 @@ public: }; private: - GDTokenizer *tokenizer; + GDScriptTokenizer *tokenizer; Node *head; Node *list; @@ -540,8 +540,8 @@ public: int get_completion_identifier_is_function(); void clear(); - GDParser(); - ~GDParser(); + GDScriptParser(); + ~GDScriptParser(); }; -#endif // PARSER_H +#endif // GDSCRIPT_PARSER_H diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 5f85158232..174bb02967 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_tokenizer.cpp */ +/* gdscript_tokenizer.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,14 +27,14 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_tokenizer.h" +#include "gdscript_tokenizer.h" -#include "gd_functions.h" +#include "gdscript_functions.h" #include "io/marshalls.h" #include "map.h" #include "print_string.h" -const char *GDTokenizer::token_names[TK_MAX] = { +const char *GDScriptTokenizer::token_names[TK_MAX] = { "Empty", "Identifier", "Constant", @@ -123,6 +123,7 @@ const char *GDTokenizer::token_names[TK_MAX] = { "'$'", "'\\n'", "PI", + "TAU", "_", "INF", "NAN", @@ -169,67 +170,68 @@ static const _bit _type_list[] = { }; struct _kws { - GDTokenizer::Token token; + GDScriptTokenizer::Token token; const char *text; }; static const _kws _keyword_list[] = { //ops - { GDTokenizer::TK_OP_IN, "in" }, - { GDTokenizer::TK_OP_NOT, "not" }, - { GDTokenizer::TK_OP_OR, "or" }, - { GDTokenizer::TK_OP_AND, "and" }, + { GDScriptTokenizer::TK_OP_IN, "in" }, + { GDScriptTokenizer::TK_OP_NOT, "not" }, + { GDScriptTokenizer::TK_OP_OR, "or" }, + { GDScriptTokenizer::TK_OP_AND, "and" }, //func - { GDTokenizer::TK_PR_FUNCTION, "func" }, - { GDTokenizer::TK_PR_CLASS, "class" }, - { GDTokenizer::TK_PR_EXTENDS, "extends" }, - { GDTokenizer::TK_PR_IS, "is" }, - { GDTokenizer::TK_PR_ONREADY, "onready" }, - { GDTokenizer::TK_PR_TOOL, "tool" }, - { GDTokenizer::TK_PR_STATIC, "static" }, - { GDTokenizer::TK_PR_EXPORT, "export" }, - { GDTokenizer::TK_PR_SETGET, "setget" }, - { GDTokenizer::TK_PR_VAR, "var" }, - { GDTokenizer::TK_PR_PRELOAD, "preload" }, - { GDTokenizer::TK_PR_ASSERT, "assert" }, - { GDTokenizer::TK_PR_YIELD, "yield" }, - { GDTokenizer::TK_PR_SIGNAL, "signal" }, - { GDTokenizer::TK_PR_BREAKPOINT, "breakpoint" }, - { GDTokenizer::TK_PR_REMOTE, "remote" }, - { GDTokenizer::TK_PR_MASTER, "master" }, - { GDTokenizer::TK_PR_SLAVE, "slave" }, - { GDTokenizer::TK_PR_SYNC, "sync" }, - { GDTokenizer::TK_PR_CONST, "const" }, - { GDTokenizer::TK_PR_ENUM, "enum" }, + { GDScriptTokenizer::TK_PR_FUNCTION, "func" }, + { GDScriptTokenizer::TK_PR_CLASS, "class" }, + { GDScriptTokenizer::TK_PR_EXTENDS, "extends" }, + { GDScriptTokenizer::TK_PR_IS, "is" }, + { GDScriptTokenizer::TK_PR_ONREADY, "onready" }, + { GDScriptTokenizer::TK_PR_TOOL, "tool" }, + { GDScriptTokenizer::TK_PR_STATIC, "static" }, + { GDScriptTokenizer::TK_PR_EXPORT, "export" }, + { GDScriptTokenizer::TK_PR_SETGET, "setget" }, + { GDScriptTokenizer::TK_PR_VAR, "var" }, + { GDScriptTokenizer::TK_PR_PRELOAD, "preload" }, + { GDScriptTokenizer::TK_PR_ASSERT, "assert" }, + { GDScriptTokenizer::TK_PR_YIELD, "yield" }, + { GDScriptTokenizer::TK_PR_SIGNAL, "signal" }, + { GDScriptTokenizer::TK_PR_BREAKPOINT, "breakpoint" }, + { GDScriptTokenizer::TK_PR_REMOTE, "remote" }, + { GDScriptTokenizer::TK_PR_MASTER, "master" }, + { GDScriptTokenizer::TK_PR_SLAVE, "slave" }, + { GDScriptTokenizer::TK_PR_SYNC, "sync" }, + { GDScriptTokenizer::TK_PR_CONST, "const" }, + { GDScriptTokenizer::TK_PR_ENUM, "enum" }, //controlflow - { GDTokenizer::TK_CF_IF, "if" }, - { GDTokenizer::TK_CF_ELIF, "elif" }, - { GDTokenizer::TK_CF_ELSE, "else" }, - { GDTokenizer::TK_CF_FOR, "for" }, - { GDTokenizer::TK_CF_WHILE, "while" }, - { GDTokenizer::TK_CF_DO, "do" }, - { GDTokenizer::TK_CF_SWITCH, "switch" }, - { GDTokenizer::TK_CF_CASE, "case" }, - { GDTokenizer::TK_CF_BREAK, "break" }, - { GDTokenizer::TK_CF_CONTINUE, "continue" }, - { GDTokenizer::TK_CF_RETURN, "return" }, - { GDTokenizer::TK_CF_MATCH, "match" }, - { GDTokenizer::TK_CF_PASS, "pass" }, - { GDTokenizer::TK_SELF, "self" }, - { GDTokenizer::TK_CONST_PI, "PI" }, - { GDTokenizer::TK_WILDCARD, "_" }, - { GDTokenizer::TK_CONST_INF, "INF" }, - { GDTokenizer::TK_CONST_NAN, "NAN" }, - { GDTokenizer::TK_ERROR, NULL } + { GDScriptTokenizer::TK_CF_IF, "if" }, + { GDScriptTokenizer::TK_CF_ELIF, "elif" }, + { GDScriptTokenizer::TK_CF_ELSE, "else" }, + { GDScriptTokenizer::TK_CF_FOR, "for" }, + { GDScriptTokenizer::TK_CF_WHILE, "while" }, + { GDScriptTokenizer::TK_CF_DO, "do" }, + { GDScriptTokenizer::TK_CF_SWITCH, "switch" }, + { GDScriptTokenizer::TK_CF_CASE, "case" }, + { GDScriptTokenizer::TK_CF_BREAK, "break" }, + { GDScriptTokenizer::TK_CF_CONTINUE, "continue" }, + { GDScriptTokenizer::TK_CF_RETURN, "return" }, + { GDScriptTokenizer::TK_CF_MATCH, "match" }, + { GDScriptTokenizer::TK_CF_PASS, "pass" }, + { GDScriptTokenizer::TK_SELF, "self" }, + { GDScriptTokenizer::TK_CONST_PI, "PI" }, + { GDScriptTokenizer::TK_CONST_TAU, "TAU" }, + { GDScriptTokenizer::TK_WILDCARD, "_" }, + { GDScriptTokenizer::TK_CONST_INF, "INF" }, + { GDScriptTokenizer::TK_CONST_NAN, "NAN" }, + { GDScriptTokenizer::TK_ERROR, NULL } }; -const char *GDTokenizer::get_token_name(Token p_token) { +const char *GDScriptTokenizer::get_token_name(Token p_token) { ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>"); return token_names[p_token]; } -bool GDTokenizer::is_token_literal(int p_offset, bool variable_safe) const { +bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const { switch (get_token(p_offset)) { // Can always be literal: case TK_IDENTIFIER: @@ -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: @@ -300,7 +303,7 @@ bool GDTokenizer::is_token_literal(int p_offset, bool variable_safe) const { } } -StringName GDTokenizer::get_token_literal(int p_offset) const { +StringName GDScriptTokenizer::get_token_literal(int p_offset) const { Token token = get_token(p_offset); switch (token) { case TK_IDENTIFIER: @@ -317,7 +320,7 @@ StringName GDTokenizer::get_token_literal(int p_offset) const { } } break; // Shouldn't get here, stuff happens case TK_BUILT_IN_FUNC: - return GDFunctions::get_func_name(get_token_built_in_func(p_offset)); + return GDScriptFunctions::get_func_name(get_token_built_in_func(p_offset)); case TK_CONSTANT: { const Variant value = get_token_constant(p_offset); @@ -362,7 +365,7 @@ static bool _is_hex(CharType c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } -void GDTokenizerText::_make_token(Token p_type) { +void GDScriptTokenizerText::_make_token(Token p_type) { TokenData &tk = tk_rb[tk_rb_pos]; @@ -372,7 +375,7 @@ void GDTokenizerText::_make_token(Token p_type) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_identifier(const StringName &p_identifier) { +void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) { TokenData &tk = tk_rb[tk_rb_pos]; @@ -384,7 +387,7 @@ void GDTokenizerText::_make_identifier(const StringName &p_identifier) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_built_in_func(GDFunctions::Function p_func) { +void GDScriptTokenizerText::_make_built_in_func(GDScriptFunctions::Function p_func) { TokenData &tk = tk_rb[tk_rb_pos]; @@ -395,7 +398,7 @@ void GDTokenizerText::_make_built_in_func(GDFunctions::Function p_func) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_constant(const Variant &p_constant) { +void GDScriptTokenizerText::_make_constant(const Variant &p_constant) { TokenData &tk = tk_rb[tk_rb_pos]; @@ -407,7 +410,7 @@ void GDTokenizerText::_make_constant(const Variant &p_constant) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_type(const Variant::Type &p_type) { +void GDScriptTokenizerText::_make_type(const Variant::Type &p_type) { TokenData &tk = tk_rb[tk_rb_pos]; @@ -419,7 +422,7 @@ void GDTokenizerText::_make_type(const Variant::Type &p_type) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_error(const String &p_error) { +void GDScriptTokenizerText::_make_error(const String &p_error) { error_flag = true; last_error = p_error; @@ -432,7 +435,7 @@ void GDTokenizerText::_make_error(const String &p_error) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_make_newline(int p_spaces) { +void GDScriptTokenizerText::_make_newline(int p_spaces) { TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_NEWLINE; @@ -442,7 +445,7 @@ void GDTokenizerText::_make_newline(int p_spaces) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDTokenizerText::_advance() { +void GDScriptTokenizerText::_advance() { if (error_flag) { //parser broke @@ -882,6 +885,9 @@ void GDTokenizerText::_advance() { return; } sign_found = true; + } else if (GETCHAR(i) == '_') { + i++; + continue; // Included for readability, shouldn't be a part of the string } else break; @@ -894,7 +900,7 @@ void GDTokenizerText::_advance() { return; } - INCPOS(str.length()); + INCPOS(i); if (hexa_found) { int64_t val = str.hex_to_int64(); _make_constant(val); @@ -960,11 +966,11 @@ void GDTokenizerText::_advance() { //built in func? - for (int i = 0; i < GDFunctions::FUNC_MAX; i++) { + for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { - if (str == GDFunctions::get_func_name(GDFunctions::Function(i))) { + if (str == GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) { - _make_built_in_func(GDFunctions::Function(i)); + _make_built_in_func(GDScriptFunctions::Function(i)); found = true; break; } @@ -1010,7 +1016,7 @@ void GDTokenizerText::_advance() { } } -void GDTokenizerText::set_code(const String &p_code) { +void GDScriptTokenizerText::set_code(const String &p_code) { code = p_code; len = p_code.length(); @@ -1029,7 +1035,7 @@ void GDTokenizerText::set_code(const String &p_code) { _advance(); } -GDTokenizerText::Token GDTokenizerText::get_token(int p_offset) const { +GDScriptTokenizerText::Token GDScriptTokenizerText::get_token(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, TK_ERROR); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, TK_ERROR); @@ -1037,7 +1043,7 @@ GDTokenizerText::Token GDTokenizerText::get_token(int p_offset) const { return tk_rb[ofs].type; } -int GDTokenizerText::get_token_line(int p_offset) const { +int GDScriptTokenizerText::get_token_line(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, -1); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, -1); @@ -1045,7 +1051,7 @@ int GDTokenizerText::get_token_line(int p_offset) const { return tk_rb[ofs].line; } -int GDTokenizerText::get_token_column(int p_offset) const { +int GDScriptTokenizerText::get_token_column(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, -1); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, -1); @@ -1053,7 +1059,7 @@ int GDTokenizerText::get_token_column(int p_offset) const { return tk_rb[ofs].col; } -const Variant &GDTokenizerText::get_token_constant(int p_offset) const { +const Variant &GDScriptTokenizerText::get_token_constant(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, tk_rb[0].constant); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, tk_rb[0].constant); @@ -1062,7 +1068,7 @@ const Variant &GDTokenizerText::get_token_constant(int p_offset) const { return tk_rb[ofs].constant; } -StringName GDTokenizerText::get_token_identifier(int p_offset) const { +StringName GDScriptTokenizerText::get_token_identifier(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, StringName()); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, StringName()); @@ -1072,17 +1078,17 @@ StringName GDTokenizerText::get_token_identifier(int p_offset) const { return tk_rb[ofs].identifier; } -GDFunctions::Function GDTokenizerText::get_token_built_in_func(int p_offset) const { +GDScriptFunctions::Function GDScriptTokenizerText::get_token_built_in_func(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, GDFunctions::FUNC_MAX); - ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, GDFunctions::FUNC_MAX); + ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX); + ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX); int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD - 1) % TK_RB_SIZE; - ERR_FAIL_COND_V(tk_rb[ofs].type != TK_BUILT_IN_FUNC, GDFunctions::FUNC_MAX); + ERR_FAIL_COND_V(tk_rb[ofs].type != TK_BUILT_IN_FUNC, GDScriptFunctions::FUNC_MAX); return tk_rb[ofs].func; } -Variant::Type GDTokenizerText::get_token_type(int p_offset) const { +Variant::Type GDScriptTokenizerText::get_token_type(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, Variant::NIL); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, Variant::NIL); @@ -1092,7 +1098,7 @@ Variant::Type GDTokenizerText::get_token_type(int p_offset) const { return tk_rb[ofs].vtype; } -int GDTokenizerText::get_token_line_indent(int p_offset) const { +int GDScriptTokenizerText::get_token_line_indent(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, 0); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, 0); @@ -1102,7 +1108,7 @@ int GDTokenizerText::get_token_line_indent(int p_offset) const { return tk_rb[ofs].constant; } -String GDTokenizerText::get_token_error(int p_offset) const { +String GDScriptTokenizerText::get_token_error(int p_offset) const { ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, String()); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, String()); @@ -1112,7 +1118,7 @@ String GDTokenizerText::get_token_error(int p_offset) const { return tk_rb[ofs].constant; } -void GDTokenizerText::advance(int p_amount) { +void GDScriptTokenizerText::advance(int p_amount) { ERR_FAIL_COND(p_amount <= 0); for (int i = 0; i < p_amount; i++) @@ -1123,7 +1129,7 @@ void GDTokenizerText::advance(int p_amount) { #define BYTECODE_VERSION 12 -Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) { +Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) { const uint8_t *buf = p_buffer.ptr(); int total_len = p_buffer.size(); @@ -1211,7 +1217,7 @@ Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) { return OK; } -Vector<uint8_t> GDTokenizerBuffer::parse_code_string(const String &p_code) { +Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) { Vector<uint8_t> buf; @@ -1220,7 +1226,7 @@ Vector<uint8_t> GDTokenizerBuffer::parse_code_string(const String &p_code) { Map<uint32_t, int> line_map; Vector<uint32_t> token_array; - GDTokenizerText tt; + GDScriptTokenizerText tt; tt.set_code(p_code); int line = -1; @@ -1369,17 +1375,17 @@ Vector<uint8_t> GDTokenizerBuffer::parse_code_string(const String &p_code) { return buf; } -GDTokenizerBuffer::Token GDTokenizerBuffer::get_token(int p_offset) const { +GDScriptTokenizerBuffer::Token GDScriptTokenizerBuffer::get_token(int p_offset) const { int offset = token + p_offset; if (offset < 0 || offset >= tokens.size()) return TK_EOF; - return GDTokenizerBuffer::Token(tokens[offset] & TOKEN_MASK); + return GDScriptTokenizerBuffer::Token(tokens[offset] & TOKEN_MASK); } -StringName GDTokenizerBuffer::get_token_identifier(int p_offset) const { +StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const { int offset = token + p_offset; @@ -1390,14 +1396,14 @@ StringName GDTokenizerBuffer::get_token_identifier(int p_offset) const { return identifiers[identifier]; } -GDFunctions::Function GDTokenizerBuffer::get_token_built_in_func(int p_offset) const { +GDScriptFunctions::Function GDScriptTokenizerBuffer::get_token_built_in_func(int p_offset) const { int offset = token + p_offset; - ERR_FAIL_INDEX_V(offset, tokens.size(), GDFunctions::FUNC_MAX); - return GDFunctions::Function(tokens[offset] >> TOKEN_BITS); + ERR_FAIL_INDEX_V(offset, tokens.size(), GDScriptFunctions::FUNC_MAX); + return GDScriptFunctions::Function(tokens[offset] >> TOKEN_BITS); } -Variant::Type GDTokenizerBuffer::get_token_type(int p_offset) const { +Variant::Type GDScriptTokenizerBuffer::get_token_type(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), Variant::NIL); @@ -1405,7 +1411,7 @@ Variant::Type GDTokenizerBuffer::get_token_type(int p_offset) const { return Variant::Type(tokens[offset] >> TOKEN_BITS); } -int GDTokenizerBuffer::get_token_line(int p_offset) const { +int GDScriptTokenizerBuffer::get_token_line(int p_offset) const { int offset = token + p_offset; int pos = lines.find_nearest(offset); @@ -1418,7 +1424,7 @@ int GDTokenizerBuffer::get_token_line(int p_offset) const { uint32_t l = lines.getv(pos); return l & TOKEN_LINE_MASK; } -int GDTokenizerBuffer::get_token_column(int p_offset) const { +int GDScriptTokenizerBuffer::get_token_column(int p_offset) const { int offset = token + p_offset; int pos = lines.find_nearest(offset); @@ -1430,13 +1436,13 @@ int GDTokenizerBuffer::get_token_column(int p_offset) const { uint32_t l = lines.getv(pos); return l >> TOKEN_LINE_BITS; } -int GDTokenizerBuffer::get_token_line_indent(int p_offset) const { +int GDScriptTokenizerBuffer::get_token_line_indent(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), 0); return tokens[offset] >> TOKEN_BITS; } -const Variant &GDTokenizerBuffer::get_token_constant(int p_offset) const { +const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), nil); @@ -1444,17 +1450,17 @@ const Variant &GDTokenizerBuffer::get_token_constant(int p_offset) const { ERR_FAIL_INDEX_V(constant, (uint32_t)constants.size(), nil); return constants[constant]; } -String GDTokenizerBuffer::get_token_error(int p_offset) const { +String GDScriptTokenizerBuffer::get_token_error(int p_offset) const { ERR_FAIL_V(String()); } -void GDTokenizerBuffer::advance(int p_amount) { +void GDScriptTokenizerBuffer::advance(int p_amount) { ERR_FAIL_INDEX(p_amount + token, tokens.size()); token += p_amount; } -GDTokenizerBuffer::GDTokenizerBuffer() { +GDScriptTokenizerBuffer::GDScriptTokenizerBuffer() { token = 0; } diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index c935ce45a1..d19367177b 100644 --- a/modules/gdscript/gd_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_tokenizer.h */ +/* gdscript_tokenizer.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,16 +27,16 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_TOKENIZER_H -#define GD_TOKENIZER_H +#ifndef GDSCRIPT_TOKENIZER_H +#define GDSCRIPT_TOKENIZER_H -#include "gd_functions.h" +#include "gdscript_functions.h" #include "string_db.h" #include "ustring.h" #include "variant.h" #include "vmap.h" -class GDTokenizer { +class GDScriptTokenizer { public: enum Token { @@ -128,6 +128,7 @@ public: TK_DOLLAR, TK_NEWLINE, TK_CONST_PI, + TK_CONST_TAU, TK_WILDCARD, TK_CONST_INF, TK_CONST_NAN, @@ -155,7 +156,7 @@ public: virtual const Variant &get_token_constant(int p_offset = 0) const = 0; virtual Token get_token(int p_offset = 0) const = 0; virtual StringName get_token_identifier(int p_offset = 0) const = 0; - virtual GDFunctions::Function get_token_built_in_func(int p_offset = 0) const = 0; + virtual GDScriptFunctions::Function get_token_built_in_func(int p_offset = 0) const = 0; virtual Variant::Type get_token_type(int p_offset = 0) const = 0; virtual int get_token_line(int p_offset = 0) const = 0; virtual int get_token_column(int p_offset = 0) const = 0; @@ -163,10 +164,10 @@ public: virtual String get_token_error(int p_offset = 0) const = 0; virtual void advance(int p_amount = 1) = 0; - virtual ~GDTokenizer(){}; + virtual ~GDScriptTokenizer(){}; }; -class GDTokenizerText : public GDTokenizer { +class GDScriptTokenizerText : public GDScriptTokenizer { enum { MAX_LOOKAHEAD = 4, @@ -180,7 +181,7 @@ class GDTokenizerText : public GDTokenizer { Variant constant; //for constant types union { Variant::Type vtype; //for type types - GDFunctions::Function func; //function for built in functions + GDScriptFunctions::Function func; //function for built in functions }; int line, col; TokenData() { @@ -193,7 +194,7 @@ class GDTokenizerText : public GDTokenizer { void _make_token(Token p_type); void _make_newline(int p_spaces = 0); void _make_identifier(const StringName &p_identifier); - void _make_built_in_func(GDFunctions::Function p_func); + void _make_built_in_func(GDScriptFunctions::Function p_func); void _make_constant(const Variant &p_constant); void _make_type(const Variant::Type &p_type); void _make_error(const String &p_error); @@ -215,7 +216,7 @@ public: void set_code(const String &p_code); virtual Token get_token(int p_offset = 0) const; virtual StringName get_token_identifier(int p_offset = 0) const; - virtual GDFunctions::Function get_token_built_in_func(int p_offset = 0) const; + virtual GDScriptFunctions::Function get_token_built_in_func(int p_offset = 0) const; virtual Variant::Type get_token_type(int p_offset = 0) const; virtual int get_token_line(int p_offset = 0) const; virtual int get_token_column(int p_offset = 0) const; @@ -225,7 +226,7 @@ public: virtual void advance(int p_amount = 1); }; -class GDTokenizerBuffer : public GDTokenizer { +class GDScriptTokenizerBuffer : public GDScriptTokenizer { enum { @@ -248,7 +249,7 @@ public: static Vector<uint8_t> parse_code_string(const String &p_code); virtual Token get_token(int p_offset = 0) const; virtual StringName get_token_identifier(int p_offset = 0) const; - virtual GDFunctions::Function get_token_built_in_func(int p_offset = 0) const; + virtual GDScriptFunctions::Function get_token_built_in_func(int p_offset = 0) const; virtual Variant::Type get_token_type(int p_offset = 0) const; virtual int get_token_line(int p_offset = 0) const; virtual int get_token_column(int p_offset = 0) const; @@ -256,7 +257,7 @@ public: virtual const Variant &get_token_constant(int p_offset = 0) const; virtual String get_token_error(int p_offset = 0) const; virtual void advance(int p_amount = 1); - GDTokenizerBuffer(); + GDScriptTokenizerBuffer(); }; -#endif // TOKENIZER_H +#endif // GDSCRIPT_TOKENIZER_H diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 036274c8f2..1e007ddb0f 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "gd_script.h" +#include "gdscript.h" #include "io/file_access_encrypted.h" #include "io/resource_loader.h" #include "os/file_access.h" @@ -41,10 +41,9 @@ ResourceFormatSaverGDScript *resource_saver_gd = NULL; void register_gdscript_types() { ClassDB::register_class<GDScript>(); - ClassDB::register_virtual_class<GDFunctionState>(); + ClassDB::register_virtual_class<GDScriptFunctionState>(); script_language_gd = memnew(GDScriptLanguage); - //script_language_gd->init(); ScriptServer::register_language(script_language_gd); resource_loader_gd = memnew(ResourceFormatLoaderGDScript); ResourceLoader::add_resource_format_loader(resource_loader_gd); diff --git a/modules/gridmap/config.py b/modules/gridmap/config.py index b3dbb9f46a..a93f4edb81 100644 --- a/modules/gridmap/config.py +++ b/modules/gridmap/config.py @@ -1,14 +1,13 @@ - - def can_build(platform): return True - def configure(env): pass def get_doc_classes(): - return ["GridMap"] + return [ + "GridMap", + ] def get_doc_path(): - return "doc_classes" + return "doc_classes" diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 5b0fe56f25..ee8ecfff66 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GridMap" inherits="Spatial" category="Core" version="3.0.alpha.custom_build"> +<class name="GridMap" inherits="Spatial" category="Core" version="3.0-alpha"> <brief_description> Node for 3D tile-based maps. </brief_description> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index cb14a5ee9c..b3a1947647 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -747,7 +747,6 @@ void GridMap::_update_octants_callback() { } while (to_delete.front()) { - memdelete(octant_map[to_delete.front()->get()]); octant_map.erase(to_delete.front()->get()); to_delete.pop_back(); } diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index f6a76ad2a1..bceb2b7db7 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -28,8 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "grid_map_editor_plugin.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/spatial_editor_plugin.h" +#include "os/input.h" #include "scene/3d/camera.h" #include "geometry.h" @@ -56,6 +58,14 @@ void GridMapEditor::_menu_option(int p_option) { switch (p_option) { + case MENU_OPTION_PREV_LEVEL: { + floor->set_value(floor->get_value() - 1); + } break; + + case MENU_OPTION_NEXT_LEVEL: { + floor->set_value(floor->get_value() + 1); + } break; + case MENU_OPTION_CONFIGURE: { } break; @@ -94,6 +104,7 @@ void GridMapEditor::_menu_option(int p_option) { } break; case MENU_OPTION_CURSOR_ROTATE_Y: { + Basis r; if (input_action == INPUT_DUPLICATE) { @@ -109,6 +120,7 @@ void GridMapEditor::_menu_option(int p_option) { _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_X: { + Basis r; if (input_action == INPUT_DUPLICATE) { @@ -125,6 +137,7 @@ void GridMapEditor::_menu_option(int p_option) { _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_Z: { + Basis r; if (input_action == INPUT_DUPLICATE) { @@ -141,6 +154,7 @@ void GridMapEditor::_menu_option(int p_option) { _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Y: { + Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 1, 0), Math_PI / 2.0); @@ -148,6 +162,7 @@ void GridMapEditor::_menu_option(int p_option) { _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_X: { + Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(1, 0, 0), Math_PI / 2.0); @@ -155,6 +170,7 @@ void GridMapEditor::_menu_option(int p_option) { _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Z: { + Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 0, 1), Math_PI / 2.0); @@ -184,6 +200,9 @@ void GridMapEditor::_menu_option(int p_option) { if (last_mouseover == Vector3(-1, -1, -1)) //nono mouseovering anythin break; + last_mouseover = selection.begin; + VS::get_singleton()->instance_set_transform(grid_instance[edit_axis], Transform(Basis(), grid_ofs)); + input_action = INPUT_DUPLICATE; selection.click = last_mouseover; selection.current = last_mouseover; @@ -198,7 +217,7 @@ void GridMapEditor::_menu_option(int p_option) { } break; case MENU_OPTION_GRIDMAP_SETTINGS: { - settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); + settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50) * EDSCALE); } break; } } @@ -551,12 +570,11 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu input_action = INPUT_NONE; _update_duplicate_indicator(); - } else { + } else if (mb->get_shift()) { input_action = INPUT_ERASE; set_items.clear(); - } - else - return false; + } else + return false; return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true); } else { @@ -829,70 +847,77 @@ void GridMapEditor::update_grid() { void GridMapEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { + switch (p_what) { - theme_pallete->connect("item_selected", this, "_item_selected_cbk"); - for (int i = 0; i < 3; i++) { + case NOTIFICATION_ENTER_TREE: { + theme_pallete->connect("item_selected", this, "_item_selected_cbk"); + for (int i = 0; i < 3; i++) { - grid[i] = VS::get_singleton()->mesh_create(); - grid_instance[i] = VS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario()); - selection_level_instance[i] = VisualServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario()); - } + grid[i] = VS::get_singleton()->mesh_create(); + grid_instance[i] = VS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario()); + selection_level_instance[i] = VisualServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario()); + } - selection_instance = VisualServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario()); - duplicate_instance = VisualServer::get_singleton()->instance_create2(duplicate_mesh, get_tree()->get_root()->get_world()->get_scenario()); + selection_instance = VisualServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario()); + duplicate_instance = VisualServer::get_singleton()->instance_create2(duplicate_mesh, get_tree()->get_root()->get_world()->get_scenario()); - _update_selection_transform(); - _update_duplicate_indicator(); - - } else if (p_what == NOTIFICATION_EXIT_TREE) { + _update_selection_transform(); + _update_duplicate_indicator(); + } break; - for (int i = 0; i < 3; i++) { + case NOTIFICATION_EXIT_TREE: { + for (int i = 0; i < 3; i++) { - VS::get_singleton()->free(grid_instance[i]); - VS::get_singleton()->free(grid[i]); - grid_instance[i] = RID(); - grid[i] = RID(); - VisualServer::get_singleton()->free(selection_level_instance[i]); - } + VS::get_singleton()->free(grid_instance[i]); + VS::get_singleton()->free(grid[i]); + grid_instance[i] = RID(); + grid[i] = RID(); + VisualServer::get_singleton()->free(selection_level_instance[i]); + } - VisualServer::get_singleton()->free(selection_instance); - VisualServer::get_singleton()->free(duplicate_instance); - selection_instance = RID(); - duplicate_instance = RID(); + VisualServer::get_singleton()->free(selection_instance); + VisualServer::get_singleton()->free(duplicate_instance); + selection_instance = RID(); + duplicate_instance = RID(); + } break; - } else if (p_what == NOTIFICATION_PROCESS) { - if (!node) { - return; - } + case NOTIFICATION_PROCESS: { + if (!node) { + return; + } - Transform xf = node->get_global_transform(); + Transform xf = node->get_global_transform(); - if (xf != grid_xform) { - for (int i = 0; i < 3; i++) { + if (xf != grid_xform) { + for (int i = 0; i < 3; i++) { - VS::get_singleton()->instance_set_transform(grid_instance[i], xf * edit_grid_xform); + VS::get_singleton()->instance_set_transform(grid_instance[i], xf * edit_grid_xform); + } + grid_xform = xf; } - grid_xform = xf; - } - Ref<MeshLibrary> cgmt = node->get_theme(); - if (cgmt.operator->() != last_theme) - update_pallete(); + Ref<MeshLibrary> cgmt = node->get_theme(); + if (cgmt.operator->() != last_theme) + update_pallete(); - if (lock_view) { + if (lock_view) { - EditorNode *editor = Object::cast_to<EditorNode>(get_tree()->get_root()->get_child(0)); + EditorNode *editor = Object::cast_to<EditorNode>(get_tree()->get_root()->get_child(0)); - Plane p; - p.normal[edit_axis] = 1.0; - p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis]; - p = node->get_transform().xform(p); // plane to snap + Plane p; + p.normal[edit_axis] = 1.0; + p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis]; + p = node->get_transform().xform(p); // plane to snap - SpatialEditorPlugin *sep = Object::cast_to<SpatialEditorPlugin>(editor->get_editor_plugin_screen()); - if (sep) - sep->snap_cursor_to_plane(p); - //editor->get_editor_plugin_screen()->call("snap_cursor_to_plane",p); - } + SpatialEditorPlugin *sep = Object::cast_to<SpatialEditorPlugin>(editor->get_editor_plugin_screen()); + if (sep) + sep->snap_cursor_to_plane(p); + //editor->get_editor_plugin_screen()->call("snap_cursor_to_plane",p); + } + } break; + + case NOTIFICATION_THEME_CHANGED: { + options->set_icon(get_icon("GridMap", "EditorIcons")); + } break; } } @@ -954,20 +979,38 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { int mw = EDITOR_DEF("editors/grid_map/palette_min_width", 230); Control *ec = memnew(Control); - ec->set_custom_minimum_size(Size2(mw, 0)); + ec->set_custom_minimum_size(Size2(mw, 0) * EDSCALE); add_child(ec); spatial_editor_hb = memnew(HBoxContainer); + spatial_editor_hb->set_h_size_flags(SIZE_EXPAND_FILL); + spatial_editor_hb->set_alignment(BoxContainer::ALIGN_END); SpatialEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb); + + Label *fl = memnew(Label); + fl->set_text(TTR("Floor:")); + spatial_editor_hb->add_child(fl); + + floor = memnew(SpinBox); + floor->set_min(-32767); + floor->set_max(32767); + floor->set_step(1); + floor->get_line_edit()->add_constant_override("minimum_spaces", 16); + + spatial_editor_hb->add_child(floor); + floor->connect("value_changed", this, "_floor_changed"); + + spatial_editor_hb->add_child(memnew(VSeparator)); + options = memnew(MenuButton); spatial_editor_hb->add_child(options); spatial_editor_hb->hide(); - options->set_text("Grid"); + options->set_text(TTR("Grid Map")); options->get_popup()->add_check_item(TTR("Snap View"), MENU_OPTION_LOCK_VIEW); options->get_popup()->add_separator(); - options->get_popup()->add_item(vformat(TTR("Prev Level (%sDown Wheel)"), keycode_get_string(KEY_MASK_CMD)), MENU_OPTION_PREV_LEVEL); - options->get_popup()->add_item(vformat(TTR("Next Level (%sUp Wheel)"), keycode_get_string(KEY_MASK_CMD)), MENU_OPTION_NEXT_LEVEL); + options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q); + options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E); options->get_popup()->add_separator(); options->get_popup()->add_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED), true); @@ -993,8 +1036,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { options->get_popup()->add_item(TTR("Create Exterior Connector"), MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR); options->get_popup()->add_item(TTR("Erase Area"), MENU_OPTION_REMOVE_AREA); options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Selection -> Duplicate"), MENU_OPTION_SELECTION_DUPLICATE, KEY_MASK_SHIFT + KEY_INSERT); - options->get_popup()->add_item(TTR("Selection -> Clear"), MENU_OPTION_SELECTION_CLEAR, KEY_MASK_SHIFT + KEY_DELETE); + options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KEY_MASK_SHIFT + KEY_C); + options->get_popup()->add_item(TTR("Clear Selection"), MENU_OPTION_SELECTION_CLEAR, KEY_MASK_SHIFT + KEY_X); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Settings"), MENU_OPTION_GRIDMAP_SETTINGS); @@ -1003,7 +1046,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { settings_dialog->set_title(TTR("GridMap Settings")); add_child(settings_dialog); settings_vbc = memnew(VBoxContainer); - settings_vbc->set_custom_minimum_size(Size2(200, 0)); + settings_vbc->set_custom_minimum_size(Size2(200, 0) * EDSCALE); settings_dialog->add_child(settings_vbc); settings_pick_distance = memnew(SpinBox); @@ -1042,20 +1085,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { add_child(theme_pallete); theme_pallete->set_v_size_flags(SIZE_EXPAND_FILL); - spatial_editor_hb->add_child(memnew(VSeparator)); - Label *fl = memnew(Label); - fl->set_text(" Floor: "); - spatial_editor_hb->add_child(fl); - - floor = memnew(SpinBox); - floor->set_min(-32767); - floor->set_max(32767); - floor->set_step(1); - floor->get_line_edit()->add_constant_override("minimum_spaces", 16); - - spatial_editor_hb->add_child(floor); - floor->connect("value_changed", this, "_floor_changed"); - edit_axis = Vector3::AXIS_Y; edit_floor[0] = -1; edit_floor[1] = -1; @@ -1250,7 +1279,9 @@ GridMapEditorPlugin::GridMapEditorPlugin(EditorNode *p_node) { gridmap_editor = memnew(GridMapEditor(editor)); SpatialEditor::get_singleton()->get_palette_split()->add_child(gridmap_editor); - SpatialEditor::get_singleton()->get_palette_split()->move_child(gridmap_editor, 0); + // TODO: make this configurable, so the user can choose were to put this, it makes more sense + // on the right, but some people might find it strange. + SpatialEditor::get_singleton()->get_palette_split()->move_child(gridmap_editor, 1); gridmap_editor->hide(); } diff --git a/modules/hdr/config.py b/modules/hdr/config.py index fb920482f5..5f133eba90 100644 --- a/modules/hdr/config.py +++ b/modules/hdr/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/jpg/config.py b/modules/jpg/config.py index fb920482f5..5f133eba90 100644 --- a/modules/jpg/config.py +++ b/modules/jpg/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/mobile_vr/config.py b/modules/mobile_vr/config.py index cf96c66125..4e1155f0c6 100644 --- a/modules/mobile_vr/config.py +++ b/modules/mobile_vr/config.py @@ -1,12 +1,14 @@ def can_build(platform): - # should probably change this to only be true on iOS and Android - return True + # should probably change this to only be true on iOS and Android + return True def configure(env): - pass + pass def get_doc_classes(): - return ["MobileVRInterface"] + return [ + "MobileVRInterface", + ] def get_doc_path(): - return "doc_classes" + return "doc_classes" diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index c945a99a9a..c99934aea9 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MobileVRInterface" inherits="ARVRInterface" category="Core" version="3.0.alpha.custom_build"> +<class name="MobileVRInterface" inherits="ARVRInterface" category="Core" version="3.0-alpha"> <brief_description> Generic mobile VR implementation </brief_description> 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 747377ae46..b652edc1c6 100644 --- a/modules/mobile_vr/mobile_interface.h +++ b/modules/mobile_vr/mobile_interface.h @@ -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 27e60c4623..18a20ecac4 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -84,12 +84,16 @@ def find_msbuild_unix(filename): 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 diff --git a/modules/mono/config.py b/modules/mono/config.py index 7ad135e0b9..b4e6433256 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -177,7 +177,11 @@ def configure(env): def get_doc_classes(): - return ["@C#", "CSharpScript", "GodotSharp"] + return [ + "@C#", + "CSharpScript", + "GodotSharp", + ] def get_doc_path(): diff --git a/modules/mono/doc_classes/@C#.xml b/modules/mono/doc_classes/@C#.xml index 487ba9835f..5d27b32200 100644 --- a/modules/mono/doc_classes/@C#.xml +++ b/modules/mono/doc_classes/@C#.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@C#" category="Core" version="3.0.alpha.custom_build"> +<class name="@C#" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml index 5f21c9774d..ccc24b832c 100644 --- a/modules/mono/doc_classes/CSharpScript.xml +++ b/modules/mono/doc_classes/CSharpScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CSharpScript" inherits="Script" category="Core" version="3.0.alpha.custom_build"> +<class name="CSharpScript" inherits="Script" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> diff --git a/modules/mono/doc_classes/GodotSharp.xml b/modules/mono/doc_classes/GodotSharp.xml index e7e06ddd8f..9edbd18fc1 100644 --- a/modules/mono/doc_classes/GodotSharp.xml +++ b/modules/mono/doc_classes/GodotSharp.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GodotSharp" inherits="Object" category="Core" version="3.0.alpha.custom_build"> +<class name="GodotSharp" inherits="Object" category="Core" version="3.0-alpha"> <brief_description> </brief_description> <description> 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 eb504ec021..a293cc2c50 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -31,12 +31,12 @@ #ifdef DEBUG_METHODS_ENABLED +#include "engine.h" #include "global_constants.h" #include "io/compression.h" #include "os/dir_access.h" #include "os/file_access.h" #include "os/os.h" -#include "project_settings.h" #include "ucaps.h" #include "../glue/cs_compressed.gen.h" @@ -320,9 +320,9 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo int global_constants_count = GlobalConstants::get_global_constant_count(); if (global_constants_count > 0) { - Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@Global Scope"); + Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope"); - ERR_EXPLAIN("Could not find `@Global Scope` in DocData"); + ERR_EXPLAIN("Could not find `@GlobalScope` in DocData"); ERR_FAIL_COND_V(!match, ERR_BUG); const DocData::ClassDoc &global_scope_doc = match->value(); @@ -1169,7 +1169,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { 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("() " OPEN_BLOCK "\treturn Engine::get_singleton()->get_singleton_object(\""); output.push_back(itype.proxy_name); output.push_back("\");\n" CLOSE_BLOCK "\n"); } @@ -1505,7 +1505,7 @@ void BindingsGenerator::_populate_object_type_interfaces() { TypeInterface itype = TypeInterface::create_object_type(type_cname, api_type); itype.base_name = ClassDB::get_parent_class(type_cname); - itype.is_singleton = ProjectSettings::get_singleton()->has_singleton(itype.proxy_name); + itype.is_singleton = Engine::get_singleton()->has_singleton(itype.proxy_name); itype.is_instantiable = ClassDB::can_instance(type_cname) && !itype.is_singleton; itype.is_reference = ClassDB::is_parent_class(type_cname, refclass_name); itype.memory_own = itype.is_reference; diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index dbe0cc294c..b88d34fc33 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -53,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/", @@ -361,16 +365,14 @@ GodotSharpBuilds::GodotSharpBuilds() { // 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", + #ifdef WINDOWS_ENABLED - // TODO: Default to MSBUILD_MONO if its csc.exe issue is fixed in the installed mono version - MSBUILD + // 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 - MSBUILD_MONO + 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)" diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index 837dbfde66..1bc1e8a515 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -221,9 +221,7 @@ 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); - } + 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")); } 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 a4e7d447dd..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 { 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/glue/glue_header.h b/modules/mono/glue/glue_header.h index 0751a0160f..75a4eb2b40 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -35,10 +35,10 @@ #include "bind/core_bind.h" #include "class_db.h" +#include "engine.h" #include "io/marshalls.h" #include "object.h" #include "os/os.h" -#include "project_settings.h" #include "reference.h" #include "variant_parser.h" diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 2656de5b14..217460a439 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "register_types.h" -#include "project_settings.h" +#include "engine.h" #include "csharp_script.h" @@ -45,7 +45,7 @@ void register_mono_types() { _godotsharp = memnew(_GodotSharp); ClassDB::register_class<_GodotSharp>(); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("GodotSharp", _GodotSharp::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", _GodotSharp::get_singleton())); script_language_cs = memnew(CSharpLanguage); script_language_cs->set_language_index(ScriptServer::get_language_count()); diff --git a/modules/ogg/config.py b/modules/ogg/config.py index ef5daca05c..5f133eba90 100644 --- a/modules/ogg/config.py +++ b/modules/ogg/config.py @@ -1,8 +1,5 @@ - def can_build(platform): -# return True - return False - + return True def configure(env): pass diff --git a/modules/openssl/config.py b/modules/openssl/config.py index fb920482f5..5f133eba90 100644 --- a/modules/openssl/config.py +++ b/modules/openssl/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/opus/SCsub b/modules/opus/SCsub index fee06bd267..6f643ef08c 100644 --- a/modules/opus/SCsub +++ b/modules/opus/SCsub @@ -3,6 +3,9 @@ Import('env') Import('env_modules') + +stub = True + env_opus = env_modules.Clone() # Thirdparty source files @@ -212,5 +215,9 @@ if env['builtin_opus']: if env['builtin_libogg']: env_opus.Append(CPPPATH=["#thirdparty/libogg"]) -# Module files -env_opus.add_source_files(env.modules_sources, "*.cpp") +if not stub: + # Module files + env_opus.add_source_files(env.modules_sources, "*.cpp") +else: + # Module files + env_opus.add_source_files(env.modules_sources, "stub/register_types.cpp") diff --git a/modules/opus/config.py b/modules/opus/config.py index ef5daca05c..60f8d838d6 100644 --- a/modules/opus/config.py +++ b/modules/opus/config.py @@ -1,8 +1,13 @@ - def can_build(platform): -# return True - return False - + return True def configure(env): pass + +def get_doc_classes(): + return [ + "AudioStreamOpus", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/opus/stub/register_types.cpp b/modules/opus/stub/register_types.cpp new file mode 100644 index 0000000000..c5ae3e274e --- /dev/null +++ b/modules/opus/stub/register_types.cpp @@ -0,0 +1,36 @@ +/*************************************************************************/ +/* 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" + +// Dummy module as libvorbis is needed by other modules (theora ...) + +void register_opus_types() {} + +void unregister_opus_types() {} diff --git a/modules/opus/stub/register_types.h b/modules/opus/stub/register_types.h new file mode 100644 index 0000000000..4517dc5df7 --- /dev/null +++ b/modules/opus/stub/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_opus_types(); +void unregister_opus_types(); diff --git a/modules/pbm/config.py b/modules/pbm/config.py index fb920482f5..5f133eba90 100644 --- a/modules/pbm/config.py +++ b/modules/pbm/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/pvr/config.py b/modules/pvr/config.py index fb920482f5..5f133eba90 100644 --- a/modules/pvr/config.py +++ b/modules/pvr/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/recast/config.py b/modules/recast/config.py index d42f07b2a9..fc074cf661 100644 --- a/modules/recast/config.py +++ b/modules/recast/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return platform != "android" - def configure(env): pass diff --git a/modules/regex/config.py b/modules/regex/config.py index 5347cfd243..cb2da26738 100644 --- a/modules/regex/config.py +++ b/modules/regex/config.py @@ -1,9 +1,14 @@ -#!/usr/bin/env python - - def can_build(platform): return True - def configure(env): pass + +def get_doc_classes(): + return [ + "RegEx", + "RegExMatch", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml new file mode 100644 index 0000000000..4cf272fe8c --- /dev/null +++ b/modules/regex/doc_classes/RegEx.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RegEx" inherits="Reference" category="Core" version="3.0-alpha"> + <brief_description> + Class for searching text for patterns using regular expressions. + </brief_description> + <description> + Regular Expression (or regex) is a compact programming language that can be used to recognise strings that follow a specific pattern, such as URLs, email addresses, complete sentences, etc. For instance, a regex of [code]ab[0-9][/code] would find any string that is [code]ab[/code] followed by any number from [code]0[/code] to [code]9[/code]. For a more in-depth look, you can easily find various tutorials and detailed explainations on the Internet. + To begin, the RegEx object needs to be compiled with the search pattern using [method compile] before it can be used. + [codeblock] + var regex = RegEx.new() + regex.compile("\\w-(\\d+)") + [/codeblock] + The search pattern must be escaped first for gdscript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code] + Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using fuctions such as [method RegExMatch.get_string] and [method RegExMatch.get_start]. + [codeblock] + var regex = RegEx.new() + regex.compile("\\w-(\\d+)") + var result = regex.search("abc n-0123") + if result: + print(result.get_string()) # Would print n-0123 + [/codeblock] + The results of capturing groups [code]()[/code] can be retrieved by passing the group number to the various functions in [RegExMatch]. Group 0 is the default and would always refer to the entire pattern. In the above example, calling [code]result.get_string(1)[/code] would give you [code]0123[/code]. + This version of RegEx also supports named capturing groups, and the names can be used to retrieve the results. If two or more groups have the same name, the name would only refer to the first one with a match. + [codeblock] + var regex = RegEx.new() + regex.compile("d(?<digit>[0-9]+)|x(?<digit>[0-9a-f]+)") + var result = regex.search("the number is x2f") + if result: + print(result.get_string("digit")) # Would print 2f + [/codeblock] + If you need to process multiple results, [method search_all] generates a list of all non-overlapping results. This can be combined with a for-loop for convenience. + [codeblock] + for result in regex.search_all("d01, d03, d0c, x3f and x42"): + print(result.get_string("digit")) + # Would print 01 03 3f 42 + # Note that d0c would not match + [/codeblock] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="clear"> + <return type="void"> + </return> + <description> + This method resets the state of the object, as it was freshly created. Namely, it unassigns the regular expression of this object. + </description> + </method> + <method name="compile"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="pattern" type="String"> + </argument> + <description> + Compiles and assign the search pattern to use. Returns OK if the compilation is successful. If an error is encountered the details are printed to STDOUT and FAILED is returned. + </description> + </method> + <method name="get_group_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of capturing groups in compiled pattern. + </description> + </method> + <method name="get_names" qualifiers="const"> + <return type="Array"> + </return> + <description> + Returns an array of names of named capturing groups in the compiled pattern. They are ordered by appearance. + </description> + </method> + <method name="get_pattern" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns the original search pattern that was compiled. + </description> + </method> + <method name="is_valid" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether this object has a valid search pattern assigned. + </description> + </method> + <method name="search" qualifiers="const"> + <return type="RegExMatch"> + </return> + <argument index="0" name="subject" type="String"> + </argument> + <argument index="1" name="offset" type="int" default="0"> + </argument> + <argument index="2" name="end" type="int" default="-1"> + </argument> + <description> + Searches the text for the compiled pattern. Returns a [RegExMatch] container of the first matching result if found, otherwise null. The region to search within can be specified without modifying where the start and end anchor would be. + </description> + </method> + <method name="search_all" qualifiers="const"> + <return type="Array"> + </return> + <argument index="0" name="subject" type="String"> + </argument> + <argument index="1" name="offset" type="int" default="0"> + </argument> + <argument index="2" name="end" type="int" default="-1"> + </argument> + <description> + Searches the text for the compiled pattern. Returns an array of [RegExMatch] containers for each non-overlapping result. If no results were found an empty array is returned instead. The region to search within can be specified without modifying where the start and end anchor would be. + </description> + </method> + <method name="sub" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="subject" type="String"> + </argument> + <argument index="1" name="replacement" type="String"> + </argument> + <argument index="2" name="all" type="bool" default="false"> + </argument> + <argument index="3" name="offset" type="int" default="0"> + </argument> + <argument index="4" name="end" type="int" default="-1"> + </argument> + <description> + Searches the text for the compiled pattern and replaces it with the specified string. Escapes and backreferences such as [code]\1[/code] and [code]\g<name>[/code] expanded and resolved. By default only the first instance is replaced but it can be changed for all instances (global replacement). The region to search within can be specified without modifying where the start and end anchor would be. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml new file mode 100644 index 0000000000..354febf89a --- /dev/null +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RegExMatch" inherits="Reference" category="Core" version="3.0-alpha"> + <brief_description> + Contains the results of a regex search. + </brief_description> + <description> + Contains the results of a single regex match returned by [method RegEx.search] and [method.RegEx.search_all]. It can be used to find the position and range of the match and its capturing groups, and it can extract its sub-string for you. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_end" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="Variant" default="0"> + </argument> + <description> + Returns the end position of the match within the source string. The end position of capturing groups can be retrieved by providing its group number as an integer or its string name (if it's a named group). The default value of 0 refers to the whole pattern. + Returns -1 if the group did not match or doesn't exist. + </description> + </method> + <method name="get_group_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of capturing groups. + </description> + </method> + <method name="get_names" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + Returns a dictionary of named groups and its corresponding group number. Only groups with that were matched are included. If multiple groups have the same name, that name would refer to the first matching one. + </description> + </method> + <method name="get_start" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="Variant" default="0"> + </argument> + <description> + Returns the starting position of the match within the source string. The starting position of capturing groups can be retrieved by providing its group number as an integer or its string name (if it's a named group). The default value of 0 refers to the whole pattern. + Returns -1 if the group did not match or doesn't exist. + </description> + </method> + <method name="get_string" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="name" type="Variant" default="0"> + </argument> + <description> + Returns the substring of the match from the source string. Capturing groups can be retrieved by providing its group number as an integer or its string name (if it's a named group). The default value of 0 refers to the whole pattern. + Returns an empty string if the group did not match or doesn't exist. + </description> + </method> + <method name="get_strings" qualifiers="const"> + <return type="Array"> + </return> + <description> + Returns an [Array] of the match and its capturing groups. + </description> + </method> + <method name="get_subject" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns the source string used with the search pattern to find this matching result. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 00e8ce0f54..daadfcc659 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -324,6 +324,21 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) return result; } +Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const { + + int last_end = -1; + Array result; + Ref<RegExMatch> match = search(p_subject, p_offset, p_end); + while (match.is_valid()) { + if (last_end == match->get_end(0)) + break; + result.push_back(match); + last_end = match->get_end(0); + match = search(p_subject, match->get_end(0), p_end); + } + return result; +} + String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const { ERR_FAIL_COND_V(!is_valid(), String()); @@ -489,6 +504,7 @@ void RegEx::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear); ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile); ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("search_all", "subject", "offset", "end"), &RegEx::search_all, DEFVAL(0), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("sub", "subject", "replacement", "all", "offset", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("is_valid"), &RegEx::is_valid); ClassDB::bind_method(D_METHOD("get_pattern"), &RegEx::get_pattern); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index bfa9c84042..21387222f2 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -88,6 +88,7 @@ public: void _init(const String &p_pattern = ""); Ref<RegExMatch> search(const String &p_subject, int p_offset = 0, int p_end = -1) const; + Array search_all(const String &p_subject, int p_offset = 0, int p_end = -1) const; String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_offset = 0, int p_end = -1) const; bool is_valid() const; diff --git a/modules/squish/config.py b/modules/squish/config.py index 9b7729bda4..97c95999c8 100644 --- a/modules/squish/config.py +++ b/modules/squish/config.py @@ -1,8 +1,6 @@ - def can_build(platform): return True - def configure(env): # Tools only, disabled for non-tools # TODO: Find a cleaner way to achieve that diff --git a/modules/stb_vorbis/config.py b/modules/stb_vorbis/config.py index fb920482f5..defe8d0c94 100644 --- a/modules/stb_vorbis/config.py +++ b/modules/stb_vorbis/config.py @@ -1,7 +1,14 @@ - def can_build(platform): return True - def configure(env): pass + +def get_doc_classes(): + return [ + "AudioStreamOGGVorbis", + "ResourceImporterOGGVorbis", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml new file mode 100644 index 0000000000..ee6c28c36a --- /dev/null +++ b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="AudioStreamOGGVorbis" inherits="AudioStream" category="Core" version="3.0-alpha"> + <brief_description> + OGG Vorbis audio stream driver. + </brief_description> + <description> + OGG Vorbis audio stream driver. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_data" qualifiers="const"> + <return type="PoolByteArray"> + </return> + <description> + </description> + </method> + <method name="get_loop_offset" qualifiers="const"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="has_loop" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_data"> + <return type="void"> + </return> + <argument index="0" name="data" type="PoolByteArray"> + </argument> + <description> + </description> + </method> + <method name="set_loop"> + <return type="void"> + </return> + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_loop_offset"> + <return type="void"> + </return> + <argument index="0" name="seconds" type="float"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="data" type="PoolByteArray" setter="set_data" getter="get_data"> + Raw audio data. + </member> + <member name="loop" type="bool" setter="set_loop" getter="has_loop"> + If [code]true[/code], audio will loop continuously. Default value: [code]false[/code]. + </member> + <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset"> + If loop is [code]true[/code], loop starts from this position, in seconds. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml b/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml new file mode 100644 index 0000000000..ce16632d6e --- /dev/null +++ b/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ResourceImporterOGGVorbis" inherits="ResourceImporter" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/svg/config.py b/modules/svg/config.py index fb920482f5..5f133eba90 100644 --- a/modules/svg/config.py +++ b/modules/svg/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/tga/config.py b/modules/tga/config.py index fb920482f5..5f133eba90 100644 --- a/modules/tga/config.py +++ b/modules/tga/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass diff --git a/modules/theora/config.py b/modules/theora/config.py index 8eefe81288..34d34f8be2 100644 --- a/modules/theora/config.py +++ b/modules/theora/config.py @@ -1,8 +1,14 @@ - def can_build(platform): -# return True - return False - + return True def configure(env): pass + +def get_doc_classes(): + return [ + "ResourceImporterTheora", + "VideoStreamTheora", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/theora/doc_classes/ResourceImporterTheora.xml b/modules/theora/doc_classes/ResourceImporterTheora.xml new file mode 100644 index 0000000000..497c938826 --- /dev/null +++ b/modules/theora/doc_classes/ResourceImporterTheora.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ResourceImporterTheora" inherits="ResourceImporter" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/theora/doc_classes/VideoStreamTheora.xml b/modules/theora/doc_classes/VideoStreamTheora.xml new file mode 100644 index 0000000000..8f155b786f --- /dev/null +++ b/modules/theora/doc_classes/VideoStreamTheora.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VideoStreamTheora" inherits="VideoStream" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_file"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_file"> + <return type="void"> + </return> + <argument index="0" name="file" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="file" type="String" setter="set_file" getter="get_file"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp index ae6961b3da..c51b87b8fc 100644 --- a/modules/theora/register_types.cpp +++ b/modules/theora/register_types.cpp @@ -28,19 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" - +#include "resource_importer_theora.h" #include "video_stream_theora.h" -static ResourceFormatLoaderVideoStreamTheora *theora_stream_loader = NULL; - void register_theora_types() { - theora_stream_loader = memnew(ResourceFormatLoaderVideoStreamTheora); - ResourceLoader::add_resource_format_loader(theora_stream_loader); +#ifdef TOOLS_ENABLED + Ref<ResourceImporterTheora> theora_import; + theora_import.instance(); + ResourceFormatImporter::get_singleton()->add_importer(theora_import); +#endif ClassDB::register_class<VideoStreamTheora>(); } void unregister_theora_types() { - - memdelete(theora_stream_loader); } diff --git a/modules/theora/resource_importer_theora.cpp b/modules/theora/resource_importer_theora.cpp new file mode 100644 index 0000000000..c25c0e7427 --- /dev/null +++ b/modules/theora/resource_importer_theora.cpp @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* resource_importer_theora.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 "resource_importer_theora.h" + +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "scene/resources/texture.h" + +String ResourceImporterTheora::get_importer_name() const { + + return "Theora"; +} + +String ResourceImporterTheora::get_visible_name() const { + + return "Theora"; +} +void ResourceImporterTheora::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("ogv"); + p_extensions->push_back("ogm"); +} + +String ResourceImporterTheora::get_save_extension() const { + return "ogvstr"; +} + +String ResourceImporterTheora::get_resource_type() const { + + return "VideoStreamTheora"; +} + +bool ResourceImporterTheora::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + + return true; +} + +int ResourceImporterTheora::get_preset_count() const { + return 0; +} +String ResourceImporterTheora::get_preset_name(int p_idx) const { + + return String(); +} + +void ResourceImporterTheora::get_import_options(List<ImportOption> *r_options, int p_preset) const { + + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); +} + +Error ResourceImporterTheora::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { + + VideoStreamTheora *stream = memnew(VideoStreamTheora); + stream->set_file(p_source_file); + + Ref<VideoStreamTheora> ogv_stream = Ref<VideoStreamTheora>(stream); + + return ResourceSaver::save(p_save_path + ".ogvstr", ogv_stream); +} + +ResourceImporterTheora::ResourceImporterTheora() { +} diff --git a/modules/theora/resource_importer_theora.h b/modules/theora/resource_importer_theora.h new file mode 100644 index 0000000000..8bf0ad38c4 --- /dev/null +++ b/modules/theora/resource_importer_theora.h @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* resource_importer_theora.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 RESOURCEIMPORTEROGGTHEORA_H +#define RESOURCEIMPORTEROGGTHEORA_H + +#include "video_stream_theora.h" + +#include "core/io/resource_import.h" + +class ResourceImporterTheora : public ResourceImporter { + GDCLASS(ResourceImporterTheora, ResourceImporter) +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + + ResourceImporterTheora(); +}; + +#endif // RESOURCEIMPORTEROGGTHEORA_H diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index c75bec31df..bc8ca23d60 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -406,20 +406,19 @@ void VideoStreamPlaybackTheora::update(float p_delta) { ogg_packet op; bool no_theora = false; + bool buffer_full = false; - while (vorbis_p) { + while (vorbis_p && !audio_done && !buffer_full) { int ret; float **pcm; - bool buffer_full = false; - /* if there's pending, decoded audio, grab it */ ret = vorbis_synthesis_pcmout(&vd, &pcm); if (ret > 0) { const int AUXBUF_LEN = 4096; int to_read = ret; - int16_t aux_buffer[AUXBUF_LEN]; + float aux_buffer[AUXBUF_LEN]; while (to_read) { @@ -429,11 +428,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) { for (int j = 0; j < m; j++) { for (int i = 0; i < vi.channels; i++) { - - int val = Math::fast_ftoi(pcm[i][j] * 32767.f); - if (val > 32767) val = 32767; - if (val < -32768) val = -32768; - aux_buffer[count++] = val; + aux_buffer[count++] = pcm[i][j]; } } @@ -602,10 +597,9 @@ bool VideoStreamPlaybackTheora::is_playing() const { void VideoStreamPlaybackTheora::set_paused(bool p_paused) { paused = p_paused; - //pau = !p_paused; }; -bool VideoStreamPlaybackTheora::is_paused(bool p_paused) const { +bool VideoStreamPlaybackTheora::is_paused() const { return paused; }; @@ -733,32 +727,10 @@ VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() { memdelete(file); }; -RES ResourceFormatLoaderVideoStreamTheora::load(const String &p_path, const String &p_original_path, Error *r_error) { - if (r_error) - *r_error = ERR_FILE_CANT_OPEN; - - VideoStreamTheora *stream = memnew(VideoStreamTheora); - stream->set_file(p_path); - - if (r_error) - *r_error = OK; - - return Ref<VideoStreamTheora>(stream); -} +void VideoStreamTheora::_bind_methods() { -void ResourceFormatLoaderVideoStreamTheora::get_recognized_extensions(List<String> *p_extensions) const { + ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file); + ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamTheora::get_file); - p_extensions->push_back("ogm"); - p_extensions->push_back("ogv"); -} -bool ResourceFormatLoaderVideoStreamTheora::handles_type(const String &p_type) const { - return (p_type == "VideoStream" || p_type == "VideoStreamTheora"); -} - -String ResourceFormatLoaderVideoStreamTheora::get_resource_type(const String &p_path) const { - - String exl = p_path.get_extension().to_lower(); - if (exl == "ogm" || exl == "ogv") - return "VideoStreamTheora"; - return ""; + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file"); } diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 484a1a7fb9..ec0e5aa34a 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -36,6 +36,7 @@ #include "os/thread.h" #include "ring_buffer.h" #include "scene/resources/video_stream.h" +#include "servers/audio_server.h" #include <theora/theoradec.h> #include <vorbis/codec.h> @@ -129,7 +130,7 @@ public: virtual bool is_playing() const; virtual void set_paused(bool p_paused); - virtual bool is_paused(bool p_paused) const; + virtual bool is_paused() const; virtual void set_loop(bool p_enable); virtual bool has_loop() const; @@ -161,10 +162,14 @@ public: class VideoStreamTheora : public VideoStream { GDCLASS(VideoStreamTheora, VideoStream); + RES_BASE_EXTENSION("ogvstr"); String file; int audio_track; +protected: + static void _bind_methods(); + public: Ref<VideoStreamPlayback> instance_playback() { Ref<VideoStreamPlaybackTheora> pb = memnew(VideoStreamPlaybackTheora); @@ -174,17 +179,10 @@ public: } void set_file(const String &p_file) { file = p_file; } + String get_file() { return file; } void set_audio_track(int p_track) { audio_track = p_track; } VideoStreamTheora() { audio_track = 0; } }; -class ResourceFormatLoaderVideoStreamTheora : public ResourceFormatLoader { -public: - 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; -}; - #endif diff --git a/modules/tinyexr/config.py b/modules/tinyexr/config.py index 3e16fd725e..e12bb398ce 100644 --- a/modules/tinyexr/config.py +++ b/modules/tinyexr/config.py @@ -1,8 +1,6 @@ - def can_build(platform): return True - def configure(env): # Tools only, disabled for non-tools # TODO: Find a cleaner way to achieve that diff --git a/modules/visual_script/config.py b/modules/visual_script/config.py index 5698a37295..6b1ce41014 100644 --- a/modules/visual_script/config.py +++ b/modules/visual_script/config.py @@ -1,8 +1,57 @@ - - def can_build(platform): return True - def configure(env): pass + +def get_doc_classes(): + return [ + "VisualScriptBasicTypeConstant", + "VisualScriptBuiltinFunc", + "VisualScriptClassConstant", + "VisualScriptComment", + "VisualScriptCondition", + "VisualScriptConstant", + "VisualScriptConstructor", + "VisualScriptCustomNode", + "VisualScriptDeconstruct", + "VisualScriptEditor", + "VisualScriptEmitSignal", + "VisualScriptEngineSingleton", + "VisualScriptExpression", + "VisualScriptFunctionCall", + "VisualScriptFunctionState", + "VisualScriptFunction", + "VisualScriptGlobalConstant", + "VisualScriptIndexGet", + "VisualScriptIndexSet", + "VisualScriptInputAction", + "VisualScriptIterator", + "VisualScriptLocalVarSet", + "VisualScriptLocalVar", + "VisualScriptMathConstant", + "VisualScriptNode", + "VisualScriptOperator", + "VisualScriptPreload", + "VisualScriptPropertyGet", + "VisualScriptPropertySet", + "VisualScriptResourcePath", + "VisualScriptReturn", + "VisualScriptSceneNode", + "VisualScriptSceneTree", + "VisualScriptSelect", + "VisualScriptSelf", + "VisualScriptSequence", + "VisualScriptSubCall", + "VisualScriptSwitch", + "VisualScriptTypeCast", + "VisualScriptVariableGet", + "VisualScriptVariableSet", + "VisualScriptWhile", + "VisualScript", + "VisualScriptYieldSignal", + "VisualScriptYield", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml new file mode 100644 index 0000000000..80b1ed86d7 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -0,0 +1,515 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScript" inherits="Script" category="Core" version="3.0-alpha"> + <brief_description> + A script implemented in the Visual Script programming environment. + </brief_description> + <description> + A script implemented in the Visual Script programming environment. The script extends the functionality of all objects that instance it. + [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. + You are most likely to use this class via the Visual Script editor or when writing plugins for it. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="add_custom_signal"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Add a custom signal with the specified name to the VisualScript. + </description> + </method> + <method name="add_function"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Add a function with the specified name to the VisualScript. + </description> + </method> + <method name="add_node"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <argument index="2" name="node" type="VisualScriptNode"> + </argument> + <argument index="3" name="position" type="Vector2" default="Vector2( 0, 0 )"> + </argument> + <description> + Add a node to a function of the VisualScript. + </description> + </method> + <method name="add_variable"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="default_value" type="Variant" default="null"> + </argument> + <argument index="2" name="export" type="bool" default="false"> + </argument> + <description> + Add a variable to the VisualScript, optionally giving it a default value or marking it as exported. + </description> + </method> + <method name="custom_signal_add_argument"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="type" type="int" enum="Variant.Type"> + </argument> + <argument index="2" name="argname" type="String"> + </argument> + <argument index="3" name="index" type="int" default="-1"> + </argument> + <description> + Add an argument to a custom signal added with [method add_custom_signal]. + </description> + </method> + <method name="custom_signal_get_argument_count" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Get the count of a custom signal's arguments. + </description> + </method> + <method name="custom_signal_get_argument_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <description> + Get the name of a custom signal's argument. + </description> + </method> + <method name="custom_signal_get_argument_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <description> + Get the type of a custom signal's argument. + </description> + </method> + <method name="custom_signal_remove_argument"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <description> + Remove a specific custom signal's argument. + </description> + </method> + <method name="custom_signal_set_argument_name"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <argument index="2" name="argname" type="String"> + </argument> + <description> + Rename a custom signal's argument. + </description> + </method> + <method name="custom_signal_set_argument_type"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <argument index="2" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + Change the type of a custom signal's argument. + </description> + </method> + <method name="custom_signal_swap_argument"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="argidx" type="int"> + </argument> + <argument index="2" name="withidx" type="int"> + </argument> + <description> + Swap two of the arguments of a custom signal. + </description> + </method> + <method name="data_connect"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_port" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <argument index="4" name="to_port" type="int"> + </argument> + <description> + Connect two data ports. The value of [code]from_node[/code]'s [code]from_port[/code] would be fed into [code]to_node[/code]'s [code]to_port[/code]. + </description> + </method> + <method name="data_disconnect"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_port" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <argument index="4" name="to_port" type="int"> + </argument> + <description> + Disconnect two data ports previously connected with [method data_connect]. + </description> + </method> + <method name="get_function_node_id" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns the id of a function's entry point node. + </description> + </method> + <method name="get_function_scroll" qualifiers="const"> + <return type="Vector2"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns the position of the center of the screen for a given function. + </description> + </method> + <method name="get_node" qualifiers="const"> + <return type="VisualScriptNode"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Returns a node given its id and its function. + </description> + </method> + <method name="get_node_position" qualifiers="const"> + <return type="Vector2"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Returns a node's position in pixels. + </description> + </method> + <method name="get_variable_default_value" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns the default (initial) value of a variable. + </description> + </method> + <method name="get_variable_export" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns whether a variable is exported. + </description> + </method> + <method name="get_variable_info" qualifiers="const"> + <return type="Dictionary"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns the info for a given variable as a dictionary. The information includes its name, type, hint and usage. + </description> + </method> + <method name="has_custom_signal" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns whether a signal exists with the specified name. + </description> + </method> + <method name="has_data_connection" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_port" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <argument index="4" name="to_port" type="int"> + </argument> + <description> + Returns whether the specified data ports are connected. + </description> + </method> + <method name="has_function" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns whether a function exists with the specified name. + </description> + </method> + <method name="has_node" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Returns whether a node exists with the given id. + </description> + </method> + <method name="has_sequence_connection" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_output" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <description> + Returns whether the specified sequence ports are connected. + </description> + </method> + <method name="has_variable" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Returns whether a variable exists with the specified name. + </description> + </method> + <method name="remove_custom_signal"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Remove a custom signal with the given name. + </description> + </method> + <method name="remove_function"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Remove a specific function and its nodes from the script. + </description> + </method> + <method name="remove_node"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Remove a specific node. + </description> + </method> + <method name="remove_variable"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Remove a variable with the given name. + </description> + </method> + <method name="rename_custom_signal"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="new_name" type="String"> + </argument> + <description> + Change the name of a custom signal. + </description> + </method> + <method name="rename_function"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="new_name" type="String"> + </argument> + <description> + Change the name of a function. + </description> + </method> + <method name="rename_variable"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="new_name" type="String"> + </argument> + <description> + Change the name of a variable. + </description> + </method> + <method name="sequence_connect"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_output" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <description> + Connect two sequence ports. The execution will flow from of [code]from_node[/code]'s [code]from_output[/code] into [code]to_node[/code]. + Unlike [method data_connect], there isn't a [code]to_port[/code], since the target node can have only one sequence port. + </description> + </method> + <method name="sequence_disconnect"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="from_node" type="int"> + </argument> + <argument index="2" name="from_output" type="int"> + </argument> + <argument index="3" name="to_node" type="int"> + </argument> + <description> + Disconnect two sequence ports previously connected with [method sequence_connect]. + </description> + </method> + <method name="set_function_scroll"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="ofs" type="Vector2"> + </argument> + <description> + Position the center of the screen for a function. + </description> + </method> + <method name="set_instance_base_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="String"> + </argument> + <description> + Set the base type of the script. + </description> + </method> + <method name="set_node_position"> + <return type="void"> + </return> + <argument index="0" name="func" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <argument index="2" name="position" type="Vector2"> + </argument> + <description> + Position a node on the screen. + </description> + </method> + <method name="set_variable_default_value"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + Change the default (initial) value of a variable. + </description> + </method> + <method name="set_variable_export"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + Change whether a variable is exported. + </description> + </method> + <method name="set_variable_info"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="value" type="Dictionary"> + </argument> + <description> + Set a variable's info, using the same format as [method get_variable_info]. + </description> + </method> + </methods> + <members> + <member name="data" type="Dictionary" setter="_set_data" getter="_get_data"> + </member> + </members> + <signals> + <signal name="node_ports_changed"> + <argument index="0" name="function" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + Emitted when the ports of a node are changed. + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml new file mode 100644 index 0000000000..6c028e5f28 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptBasicTypeConstant" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node representing a constant from the base types. + </brief_description> + <description> + A Visual Script node representing a constant from base types, such as [Vector3.AXIS_X]. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_basic_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="get_basic_type_constant" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_basic_type"> + <return type="void"> + </return> + <argument index="0" name="name" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + <method name="set_basic_type_constant"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + The type to get the constant from. + </member> + <member name="constant" type="String" setter="set_basic_type_constant" getter="get_basic_type_constant"> + The name of the constant to return. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml new file mode 100644 index 0000000000..27231574d7 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptBuiltinFunc" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node used to call built-in functions. + </brief_description> + <description> + A built-in function used inside a [VisualScript]. It is usually a math function or an utility function. + See also [@GDScript], for the same functions in the GDScript language. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_func"> + <return type="int" enum="VisualScriptBuiltinFunc.BuiltinFunc"> + </return> + <description> + </description> + </method> + <method name="set_func"> + <return type="void"> + </return> + <argument index="0" name="which" type="int" enum="VisualScriptBuiltinFunc.BuiltinFunc"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="function" type="int" setter="set_func" getter="get_func" enum="VisualScriptBuiltinFunc.BuiltinFunc"> + The function to be executed. + </member> + </members> + <constants> + <constant name="MATH_SIN" value="0"> + Return the sine of the input. + </constant> + <constant name="MATH_COS" value="1"> + Return the cosine of the input. + </constant> + <constant name="MATH_TAN" value="2"> + Return the tangent of the input. + </constant> + <constant name="MATH_SINH" value="3"> + Return the hyperbolic sine of the input. + </constant> + <constant name="MATH_COSH" value="4"> + Return the hyperbolic cosine of the input. + </constant> + <constant name="MATH_TANH" value="5"> + Return the hyperbolic tangent of the input. + </constant> + <constant name="MATH_ASIN" value="6"> + Return the arc sine of the input. + </constant> + <constant name="MATH_ACOS" value="7"> + Return the arc cosine of the input. + </constant> + <constant name="MATH_ATAN" value="8"> + Return the arc tangent of the input. + </constant> + <constant name="MATH_ATAN2" value="9"> + Return the arc tangent of the input, using the signs of both parameters to determine the exact angle. + </constant> + <constant name="MATH_SQRT" value="10"> + Return the square root of the input. + </constant> + <constant name="MATH_FMOD" value="11"> + Return the remainder of one input divided by the other, using floating-point numbers. + </constant> + <constant name="MATH_FPOSMOD" value="12"> + Return the positive remainder of one input divided by the other, using floating-point numbers. + </constant> + <constant name="MATH_FLOOR" value="13"> + Return the input rounded down. + </constant> + <constant name="MATH_CEIL" value="14"> + Return the input rounded up. + </constant> + <constant name="MATH_ROUND" value="15"> + Return the input rounded to the nearest integer. + </constant> + <constant name="MATH_ABS" value="16"> + Return the absolute value of the input. + </constant> + <constant name="MATH_SIGN" value="17"> + Return the sign of the input, turning it into 1, -1, or 0. Useful to determine if the input is positive or negative. + </constant> + <constant name="MATH_POW" value="18"> + Return the input raised to a given power. + </constant> + <constant name="MATH_LOG" value="19"> + Return the natural logarithm of the input. Note that this is not the typical base-10 logarithm function calculators use. + </constant> + <constant name="MATH_EXP" value="20"> + Return [b]e[/b] raised to the power of the input. [b]e[/b] sometimes called "Euler's number" is a mathematical constant whose value is approximately 2.71828. + </constant> + <constant name="MATH_ISNAN" value="21"> + Return whether the input is NaN (Not a Number) or not. NaN is usually produced by dividing 0 by 0, though other ways exist. + </constant> + <constant name="MATH_ISINF" value="22"> + Return whether the input is an infinite floating-point number or not. Infinity is usually produced by dividing a number by 0, though other ways exist. + </constant> + <constant name="MATH_EASE" value="23"> + Easing function, based on exponent. 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. + </constant> + <constant name="MATH_DECIMALS" value="24"> + Return the number of digit places after the decimal that the first non-zero digit occurs. + </constant> + <constant name="MATH_STEPIFY" value="25"> + Return the input snapped to a given step. + </constant> + <constant name="MATH_LERP" value="26"> + Return a number linearly interpolated between the first two inputs, based on the third input. Uses the formula [code]a + (a - b) * t[/code]. + </constant> + <constant name="MATH_INVERSE_LERP" value="27"> + </constant> + <constant name="MATH_RANGE_LERP" value="28"> + </constant> + <constant name="MATH_DECTIME" value="29"> + Return the result of 'value' decreased by 'step' * 'amount'. + </constant> + <constant name="MATH_RANDOMIZE" value="30"> + Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. + </constant> + <constant name="MATH_RAND" value="31"> + Return a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function. + </constant> + <constant name="MATH_RANDF" value="32"> + Return a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication. + </constant> + <constant name="MATH_RANDOM" value="33"> + Return a random floating-point value between the two inputs. + </constant> + <constant name="MATH_SEED" value="34"> + Set the seed for the random number generator. + </constant> + <constant name="MATH_RANDSEED" value="35"> + Return a random value from the given seed, along with the new seed. + </constant> + <constant name="MATH_DEG2RAD" value="36"> + Convert the input from degrees to radians. + </constant> + <constant name="MATH_RAD2DEG" value="37"> + Convert the input from radians to degrees. + </constant> + <constant name="MATH_LINEAR2DB" value="38"> + Convert the input from linear volume to decibel volume. + </constant> + <constant name="MATH_DB2LINEAR" value="39"> + Convert the input from decibel volume to linear volume. + </constant> + <constant name="MATH_WRAP" value="40"> + </constant> + <constant name="MATH_WRAPF" value="41"> + </constant> + <constant name="LOGIC_MAX" value="42"> + Return the greater of the two numbers, also known as their maximum. + </constant> + <constant name="LOGIC_MIN" value="43"> + Return the lesser of the two numbers, also known as their minimum. + </constant> + <constant name="LOGIC_CLAMP" value="44"> + Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to `min(max(input, range_low), range_high)` + </constant> + <constant name="LOGIC_NEAREST_PO2" value="45"> + Return the nearest power of 2 to the input. + </constant> + <constant name="OBJ_WEAKREF" value="46"> + Create a [WeakRef] from the input. + </constant> + <constant name="FUNC_FUNCREF" value="47"> + Create a [FuncRef] from the input. + </constant> + <constant name="TYPE_CONVERT" value="48"> + Convert between types. + </constant> + <constant name="TYPE_OF" value="49"> + Return the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned. + </constant> + <constant name="TYPE_EXISTS" value="50"> + Checks if a type is registered in the [ClassDB]. + </constant> + <constant name="TEXT_CHAR" value="51"> + Return a character with the given ascii value. + </constant> + <constant name="TEXT_STR" value="52"> + Convert the input to a string. + </constant> + <constant name="TEXT_PRINT" value="53"> + Print the given string to the output window. + </constant> + <constant name="TEXT_PRINTERR" value="54"> + Print the given string to the standard error output. + </constant> + <constant name="TEXT_PRINTRAW" value="55"> + Print the given string to the standard output, without adding a newline. + </constant> + <constant name="VAR_TO_STR" value="56"> + Serialize a [Variant] to a string. + </constant> + <constant name="STR_TO_VAR" value="57"> + Deserialize a [Variant] from a string serialized using [VAR_TO_STR]. + </constant> + <constant name="VAR_TO_BYTES" value="58"> + Serialize a [Variant] to a [PoolByteArray]. + </constant> + <constant name="BYTES_TO_VAR" value="59"> + Deserialize a [Variant] from a [PoolByteArray] serialized using [VAR_TO_BYTES]. + </constant> + <constant name="COLORN" value="60"> + Return the [Color] with the given name and alpha ranging from 0 to 1. Note: names are defined in color_names.inc. + </constant> + <constant name="FUNC_MAX" value="61"> + The maximum value the [member function] property can have. + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml new file mode 100644 index 0000000000..e6498e92ad --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptClassConstant" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Gets a constant from a given class. + </brief_description> + <description> + This node returns a constant from a given class, such as [@GlobalScope.TYPE_INT]. See the given class' documentation for available constants. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (variant): [code]value[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_base_type"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_class_constant"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_class_constant"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + The constant's parent class. + </member> + <member name="constant" type="String" setter="set_class_constant" getter="get_class_constant"> + The constant to return. See the given class for its available constants. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptComment.xml b/modules/visual_script/doc_classes/VisualScriptComment.xml new file mode 100644 index 0000000000..ea4545f8ef --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptComment.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptComment" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node used to annotate the script. + </brief_description> + <description> + A Visual Script node used to display annotations in the script, so that code may be documented. + Comment nodes can be resized so they encompass a group of nodes. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_description" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_size" qualifiers="const"> + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="get_title" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_description"> + <return type="void"> + </return> + <argument index="0" name="description" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_size"> + <return type="void"> + </return> + <argument index="0" name="size" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="set_title"> + <return type="void"> + </return> + <argument index="0" name="title" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="description" type="String" setter="set_description" getter="get_description"> + The text inside the comment node. + </member> + <member name="size" type="Vector2" setter="set_size" getter="get_size"> + The comment node's size (in pixels). + </member> + <member name="title" type="String" setter="set_title" getter="get_title"> + The comment node's title. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptCondition.xml b/modules/visual_script/doc_classes/VisualScriptCondition.xml new file mode 100644 index 0000000000..2a30c604a5 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptCondition.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptCondition" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node which branches the flow. + </brief_description> + <description> + A Visual Script node that checks a [bool] input port. If [code]true[/code] it will exit via the “true” sequence port. If [code]false[/code] it will exit via the "false" sequence port. After exiting either, it exits via the “done” port. Sequence ports may be left disconnected. + [b]Input Ports:[/b] + - Sequence: [code]if (cond) is[/code] + - Data (boolean): [code]cond[/code] + [b]Output Ports:[/b] + - Sequence: [code]true[/code] + - Sequence: [code]false[/code] + - Sequence: [code]done[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptConstant.xml b/modules/visual_script/doc_classes/VisualScriptConstant.xml new file mode 100644 index 0000000000..51c6d19238 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptConstant.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptConstant" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Gets a contant's value. + </brief_description> + <description> + This node returns a constant's value. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (variant): [code]get[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_constant_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="get_constant_value" qualifiers="const"> + <return type="Variant"> + </return> + <description> + </description> + </method> + <method name="set_constant_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + <method name="set_constant_value"> + <return type="void"> + </return> + <argument index="0" name="value" type="Variant"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="type" type="int" setter="set_constant_type" getter="get_constant_type" enum="Variant.Type"> + The constant's type. + </member> + <member name="value" type="Variant" setter="set_constant_value" getter="get_constant_value"> + The constant's value. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptConstructor.xml b/modules/visual_script/doc_classes/VisualScriptConstructor.xml new file mode 100644 index 0000000000..91df52e893 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptConstructor.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptConstructor" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node which calls a base type constructor. + </brief_description> + <description> + A Visual Script node which calls a base type constructor. It can be used for type conversion as well. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_constructor" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> + <method name="get_constructor_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_constructor"> + <return type="void"> + </return> + <argument index="0" name="constructor" type="Dictionary"> + </argument> + <description> + </description> + </method> + <method name="set_constructor_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="constructor" type="Dictionary" setter="set_constructor" getter="get_constructor"> + The constructor function's method info. Has roughly the following structure: + [codeblock] + { + name = "string", + args = [{ + name = "string" + class_name = "string" + type = TYPE_* + hint = PROPERTY_HINT_* + hint_string = "string" + }] + default_args = [] # Array of variants + flags = METHOD_FLAG_* + id = 0 + return = {type = TYPE_*} + } + [/codeblock] + </member> + <member name="type" type="int" setter="set_constructor_type" getter="get_constructor_type" enum="Variant.Type"> + The type to be constructed. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml new file mode 100644 index 0000000000..38c325cfb7 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptCustomNode" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A scripted Visual Script node. + </brief_description> + <description> + A custom Visual Script node which can be scripted in powerful ways. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="_get_caption" qualifiers="virtual"> + <return type="String"> + </return> + <description> + Return the node's title. + </description> + </method> + <method name="_get_category" qualifiers="virtual"> + <return type="String"> + </return> + <description> + Return the node's category. + </description> + </method> + <method name="_get_input_value_port_count" qualifiers="virtual"> + <return type="int"> + </return> + <description> + Return the count of input value ports. + </description> + </method> + <method name="_get_input_value_port_name" qualifiers="virtual"> + <return type="String"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return the specified input port's name. + </description> + </method> + <method name="_get_input_value_port_type" qualifiers="virtual"> + <return type="int"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return the specified input port's type. See the TYPE_* enum in [@GlobalScope]. + </description> + </method> + <method name="_get_output_sequence_port_count" qualifiers="virtual"> + <return type="int"> + </return> + <description> + Return the amount of output [b]sequence[/b] ports. + </description> + </method> + <method name="_get_output_sequence_port_text" qualifiers="virtual"> + <return type="String"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return the specified [b]sequence[/b] output's name. + </description> + </method> + <method name="_get_output_value_port_count" qualifiers="virtual"> + <return type="int"> + </return> + <description> + Return the amount of output value ports. + </description> + </method> + <method name="_get_output_value_port_name" qualifiers="virtual"> + <return type="String"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return the specified output's name. + </description> + </method> + <method name="_get_output_value_port_type" qualifiers="virtual"> + <return type="int"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return the specified output's type. See the TYPE_* enum in [@GlobalScope]. + </description> + </method> + <method name="_get_text" qualifiers="virtual"> + <return type="String"> + </return> + <description> + Return the custom node's text, which is shown right next to the input [b]sequence[/b] port (if there is none, on the place that is usually taken by it). + </description> + </method> + <method name="_get_working_memory_size" qualifiers="virtual"> + <return type="int"> + </return> + <description> + Return the size of the custom node's working memory. See [method _step] for more details. + </description> + </method> + <method name="_has_input_sequence_port" qualifiers="virtual"> + <return type="bool"> + </return> + <description> + Return whether the custom node has an input [b]sequence[/b] port. + </description> + </method> + <method name="_step" qualifiers="virtual"> + <return type="Variant"> + </return> + <argument index="0" name="inputs" type="Array"> + </argument> + <argument index="1" name="outputs" type="Array"> + </argument> + <argument index="2" name="start_mode" type="int"> + </argument> + <argument index="3" name="working_mem" type="Array"> + </argument> + <description> + Execute the custom node's logic, returning the index of the output sequence port to use or a [String] when there is an error. + + The [code]inputs[/code] array contains the values of the input ports. + [code]outputs[/code] is an array whose indices should be set to the respective outputs. + The [code]start_mode[/code] is usually [code]START_MODE_BEGIN_SEQUENCE[/code], unless you have used the STEP_* constants. + [code]working_mem[/code] is an array which can be used to persist information between runs of the custom node. + + When returning, you can mask the returned value with one of the STEP_* constants. + </description> + </method> + </methods> + <constants> + <constant name="START_MODE_BEGIN_SEQUENCE" value="0"> + The start mode used the first time when [method _step] is called. + </constant> + <constant name="START_MODE_CONTINUE_SEQUENCE" value="1"> + The start mode used when [method _step] is called after coming back from a STEP_PUSH_STACK_BIT. + </constant> + <constant name="START_MODE_RESUME_YIELD" value="2"> + The start mode used when [method _step] is called after resuming from STEP_YIELD_BIT. + </constant> + <constant name="STEP_PUSH_STACK_BIT" value="16777216" enum=""> + Hint used by [method _step] to tell that control should return to it when there is no other node left to execute. + This is used by [VisualScriptCondition] to redirect the sequence to the "Done" port after the true/false branch has finished execution. + </constant> + <constant name="STEP_GO_BACK_BIT" value="33554432" enum=""> + Hint used by [method _step] to tell that control should return back, either hitting a previous STEP_PUSH_STACK_BIT or exiting the function. + </constant> + <constant name="STEP_NO_ADVANCE_BIT" value="67108864" enum=""> + </constant> + <constant name="STEP_EXIT_FUNCTION_BIT" value="134217728" enum=""> + Hint used by [method _step] to tell that control should stop and exit the function. + </constant> + <constant name="STEP_YIELD_BIT" value="268435456" enum=""> + Hint used by [method _step] to tell that the function should be yielded. + Using this requires you to have at least one working memory slot, which is used for the [VisualScriptFunctionState]. + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml b/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml new file mode 100644 index 0000000000..cbed3ba22c --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptDeconstruct" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node which deconstructs a base type instance into its parts. + </brief_description> + <description> + A Visual Script node which deconstructs a base type instance into its parts. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_deconstruct_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_deconstruct_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="elem_cache" type="Array" setter="_set_elem_cache" getter="_get_elem_cache"> + </member> + <member name="type" type="int" setter="set_deconstruct_type" getter="get_deconstruct_type" enum="Variant.Type"> + The type to deconstruct. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptEditor.xml b/modules/visual_script/doc_classes/VisualScriptEditor.xml new file mode 100644 index 0000000000..70d52b2bd7 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptEditor.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptEditor" inherits="Object" category="Core" version="3.0.alpha.custom_build"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="add_custom_node"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="category" type="String"> + </argument> + <argument index="2" name="script" type="Script"> + </argument> + <description> + Add a custom Visual Script node to the editor. It'll be placed under "Custom Nodes" with the [code]category[/code] as the parameter. + </description> + </method> + <method name="remove_custom_node"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="category" type="String"> + </argument> + <description> + Remove a custom Visual Script node from the editor. Custom nodes already placed on scripts won't be removed. + </description> + </method> + </methods> + <signals> + <signal name="custom_nodes_updated"> + <description> + Emitted when a custom Visual Script node is added or removed. + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml new file mode 100644 index 0000000000..669276f0d0 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptEmitSignal" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Emits a specified signal. + </brief_description> + <description> + Emits a specified signal when it is executed. + [b]Input Ports:[/b] + - Sequence: [code]emit[/code] + [b]Output Ports:[/b] + - Sequence + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_signal" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_signal"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="signal" type="String" setter="set_signal" getter="get_signal"> + The signal to emit. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml b/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml new file mode 100644 index 0000000000..6703ff4eda --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptEngineSingleton" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + A Visual Script node returning a singleton from [@GlobalScope] + </brief_description> + <description> + A Visual Script node returning a singleton from [@GlobalScope] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_singleton"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_singleton"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="constant" type="String" setter="set_singleton" getter="get_singleton"> + The singleton's name. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptExpression.xml b/modules/visual_script/doc_classes/VisualScriptExpression.xml new file mode 100644 index 0000000000..fb3b6ef19d --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptExpression.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptExpression" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunction.xml b/modules/visual_script/doc_classes/VisualScriptFunction.xml new file mode 100644 index 0000000000..d77169679b --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptFunction.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptFunction" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml new file mode 100644 index 0000000000..7a0a7c9f55 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptFunctionCall" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_base_path" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + </description> + </method> + <method name="get_base_script" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_base_type" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_basic_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="get_call_mode" qualifiers="const"> + <return type="int" enum="VisualScriptFunctionCall.CallMode"> + </return> + <description> + </description> + </method> + <method name="get_function" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_rpc_call_mode" qualifiers="const"> + <return type="int" enum="VisualScriptFunctionCall.RPCCallMode"> + </return> + <description> + </description> + </method> + <method name="get_singleton" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_use_default_args" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_validate" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_base_path"> + <return type="void"> + </return> + <argument index="0" name="base_path" type="NodePath"> + </argument> + <description> + </description> + </method> + <method name="set_base_script"> + <return type="void"> + </return> + <argument index="0" name="base_script" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="base_type" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_basic_type"> + <return type="void"> + </return> + <argument index="0" name="basic_type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + <method name="set_call_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptFunctionCall.CallMode"> + </argument> + <description> + </description> + </method> + <method name="set_function"> + <return type="void"> + </return> + <argument index="0" name="function" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_rpc_call_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptFunctionCall.RPCCallMode"> + </argument> + <description> + </description> + </method> + <method name="set_singleton"> + <return type="void"> + </return> + <argument index="0" name="singleton" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_use_default_args"> + <return type="void"> + </return> + <argument index="0" name="amount" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_validate"> + <return type="void"> + </return> + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="argument_cache" type="Dictionary" setter="_set_argument_cache" getter="_get_argument_cache"> + </member> + <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + </member> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + </member> + <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + </member> + <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptFunctionCall.CallMode"> + </member> + <member name="function" type="String" setter="set_function" getter="get_function"> + </member> + <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + </member> + <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" enum="VisualScriptFunctionCall.RPCCallMode"> + </member> + <member name="singleton" type="String" setter="set_singleton" getter="get_singleton"> + </member> + <member name="use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args"> + </member> + <member name="validate" type="bool" setter="set_validate" getter="get_validate"> + </member> + </members> + <constants> + <constant name="CALL_MODE_SELF" value="0"> + </constant> + <constant name="CALL_MODE_NODE_PATH" value="1"> + </constant> + <constant name="CALL_MODE_INSTANCE" value="2"> + </constant> + <constant name="CALL_MODE_BASIC_TYPE" value="3"> + </constant> + <constant name="CALL_MODE_SINGLETON" value="4"> + </constant> + <constant name="RPC_DISABLED" value="0"> + </constant> + <constant name="RPC_RELIABLE" value="1"> + </constant> + <constant name="RPC_UNRELIABLE" value="2"> + </constant> + <constant name="RPC_RELIABLE_TO_ID" value="3"> + </constant> + <constant name="RPC_UNRELIABLE_TO_ID" value="4"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml new file mode 100644 index 0000000000..9b30f62236 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptFunctionState" inherits="Reference" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="connect_to_signal"> + <return type="void"> + </return> + <argument index="0" name="obj" type="Object"> + </argument> + <argument index="1" name="signals" type="String"> + </argument> + <argument index="2" name="args" type="Array"> + </argument> + <description> + </description> + </method> + <method name="is_valid" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="resume"> + <return type="Variant"> + </return> + <argument index="0" name="args" type="Array" default="null"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml new file mode 100644 index 0000000000..961244fe88 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptGlobalConstant" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_global_constant"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="set_global_constant"> + <return type="void"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="constant" type="int" setter="set_global_constant" getter="get_global_constant"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml new file mode 100644 index 0000000000..c5229f7678 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptIndexGet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml new file mode 100644 index 0000000000..27646b4a5f --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptIndexSet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptInputAction.xml b/modules/visual_script/doc_classes/VisualScriptInputAction.xml new file mode 100644 index 0000000000..7f6d13264e --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptInputAction.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptInputAction" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_action_mode" qualifiers="const"> + <return type="int" enum="VisualScriptInputAction.Mode"> + </return> + <description> + </description> + </method> + <method name="get_action_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_action_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptInputAction.Mode"> + </argument> + <description> + </description> + </method> + <method name="set_action_name"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="action" type="String" setter="set_action_name" getter="get_action_name"> + </member> + <member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" enum="VisualScriptInputAction.Mode"> + </member> + </members> + <constants> + <constant name="MODE_PRESSED" value="0"> + </constant> + <constant name="MODE_RELEASED" value="1"> + </constant> + <constant name="MODE_JUST_PRESSED" value="2"> + </constant> + <constant name="MODE_JUST_RELEASED" value="3"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIterator.xml b/modules/visual_script/doc_classes/VisualScriptIterator.xml new file mode 100644 index 0000000000..fc905d6c39 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptIterator.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptIterator" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Steps through items in a given input. + </brief_description> + <description> + This node steps through each item in a given input. Input can be any sequence data type, such as an [Array] or [String]. When each item has been processed, execution passed out the [code]exit[/code] Sequence port. + [b]Input Ports:[/b] + - Sequence: [code]for (elem) in (input)[/code] + - Data (variant): [code]input[/code] + [b]Output Ports:[/b] + - Sequence: [code]each[/code] + - Sequence: [code]exit[/code] + - Data (variant): [code]elem[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml new file mode 100644 index 0000000000..ff77dfac0d --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptLocalVar" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Gets a local variable's value. + </brief_description> + <description> + Returns a local variable's value. "Var Name" must be supplied, with an optional type. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (variant): [code]get[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_var_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_var_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_var_name"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_var_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type"> + The local variable's type. + </member> + <member name="var_name" type="String" setter="set_var_name" getter="get_var_name"> + The local variable's name. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml new file mode 100644 index 0000000000..07b01d4576 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptLocalVarSet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Changes a local variable's value. + </brief_description> + <description> + Changes a local variable's value to the given input. The new value is also provided on an output Data port. + [b]Input Ports:[/b] + - Sequence + - Data (variant): [code]set[/code] + [b]Output Ports:[/b] + - Sequence + - Data (variant): [code]get[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_var_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_var_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_var_name"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_var_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type"> + The local variable's type. + </member> + <member name="var_name" type="String" setter="set_var_name" getter="get_var_name"> + The local variable's name. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptMathConstant.xml b/modules/visual_script/doc_classes/VisualScriptMathConstant.xml new file mode 100644 index 0000000000..817bcb5ce2 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptMathConstant.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptMathConstant" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Commonly used mathematical constants. + </brief_description> + <description> + Provides common math constants, such as Pi or Euler's constant, on an output Data port. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (variant): [code]get[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_math_constant"> + <return type="int" enum="VisualScriptMathConstant.MathConstant"> + </return> + <description> + </description> + </method> + <method name="set_math_constant"> + <return type="void"> + </return> + <argument index="0" name="which" type="int" enum="VisualScriptMathConstant.MathConstant"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="constant" type="int" setter="set_math_constant" getter="get_math_constant" enum="VisualScriptMathConstant.MathConstant"> + The math constant. + </member> + </members> + <constants> + <constant name="MATH_CONSTANT_ONE" value="0"> + Unity: [code]1[/code] + </constant> + <constant name="MATH_CONSTANT_PI" value="1"> + Pi: [code]3.141593[/code] + </constant> + <constant name="MATH_CONSTANT_HALF_PI" value="2"> + Pi divided by two: [code]1.570796[/code] + </constant> + <constant name="MATH_CONSTANT_TAU" value="3"> + Tau: [code]6.283185[/code] + </constant> + <constant name="MATH_CONSTANT_E" value="4"> + Natural log: [code]2.718282[/code] + </constant> + <constant name="MATH_CONSTANT_SQRT2" value="5"> + Square root of two: [code]1.414214[/code] + </constant> + <constant name="MATH_CONSTANT_INF" value="6"> + Infinity: [code]inf[/code] + </constant> + <constant name="MATH_CONSTANT_NAN" value="7"> + Not a number: [code]nan[/code] + </constant> + <constant name="MATH_CONSTANT_MAX" value="8"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptNode.xml b/modules/visual_script/doc_classes/VisualScriptNode.xml new file mode 100644 index 0000000000..f6f2867172 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptNode.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptNode" inherits="Resource" category="Core" version="3.0-alpha"> + <brief_description> + A node which is part of a [VisualScript]. + </brief_description> + <description> + A node which is part of a [VisualScript]. Not to be confused with [Node], which is a part of a [SceneTree]. + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_default_input_value" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="port_idx" type="int"> + </argument> + <description> + Returns the default value of a given port. The default value is used when nothing is connected to the port. + </description> + </method> + <method name="get_visual_script" qualifiers="const"> + <return type="VisualScript"> + </return> + <description> + Returns the [VisualScript] instance the node is bound to. + </description> + </method> + <method name="ports_changed_notify"> + <return type="void"> + </return> + <description> + Notify that the node's ports have changed. Usually used in conjunction with [VisualScriptCustomNode] . + </description> + </method> + <method name="set_default_input_value"> + <return type="void"> + </return> + <argument index="0" name="port_idx" type="int"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + Change the default value of a given port. + </description> + </method> + </methods> + <members> + <member name="_default_input_values" type="Array" setter="_set_default_input_values" getter="_get_default_input_values"> + </member> + </members> + <signals> + <signal name="ports_changed"> + <description> + Emitted when the available input/output ports are changed. + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptOperator.xml b/modules/visual_script/doc_classes/VisualScriptOperator.xml new file mode 100644 index 0000000000..bf4032c09c --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptOperator.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptOperator" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + [b]Input Ports:[/b] + - Data (variant): [code]A[/code] + - Data (variant): [code]B[/code] + [b]Output Ports:[/b] + - Data (variant): [code]result[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_operator" qualifiers="const"> + <return type="int" enum="Variant.Operator"> + </return> + <description> + </description> + </method> + <method name="get_typed" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_operator"> + <return type="void"> + </return> + <argument index="0" name="op" type="int" enum="Variant.Operator"> + </argument> + <description> + </description> + </method> + <method name="set_typed"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="Variant.Operator"> + </member> + <member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPreload.xml b/modules/visual_script/doc_classes/VisualScriptPreload.xml new file mode 100644 index 0000000000..4a71e23809 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptPreload.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptPreload" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Creates a new [Resource] or loads one from the filesystem. + </brief_description> + <description> + Creates a new [Resource] or loads one from the filesystem. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (object): [code]res[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_preload" qualifiers="const"> + <return type="Resource"> + </return> + <description> + </description> + </method> + <method name="set_preload"> + <return type="void"> + </return> + <argument index="0" name="resource" type="Resource"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="resource" type="Resource" setter="set_preload" getter="get_preload"> + The [Resource] to load. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml new file mode 100644 index 0000000000..eb5c52f4be --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptPropertyGet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_base_path" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + </description> + </method> + <method name="get_base_script" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_base_type" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_basic_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="get_call_mode" qualifiers="const"> + <return type="int" enum="VisualScriptPropertyGet.CallMode"> + </return> + <description> + </description> + </method> + <method name="get_index" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_property" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_base_path"> + <return type="void"> + </return> + <argument index="0" name="base_path" type="NodePath"> + </argument> + <description> + </description> + </method> + <method name="set_base_script"> + <return type="void"> + </return> + <argument index="0" name="base_script" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="base_type" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_basic_type"> + <return type="void"> + </return> + <argument index="0" name="basic_type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + <method name="set_call_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptPropertyGet.CallMode"> + </argument> + <description> + </description> + </method> + <method name="set_index"> + <return type="void"> + </return> + <argument index="0" name="index" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_property"> + <return type="void"> + </return> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + </member> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + </member> + <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + </member> + <member name="index" type="String" setter="set_index" getter="get_index"> + </member> + <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + </member> + <member name="property" type="String" setter="set_property" getter="get_property"> + </member> + <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertyGet.CallMode"> + </member> + <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" enum="Variant.Type"> + </member> + </members> + <constants> + <constant name="CALL_MODE_SELF" value="0"> + </constant> + <constant name="CALL_MODE_NODE_PATH" value="1"> + </constant> + <constant name="CALL_MODE_INSTANCE" value="2"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml new file mode 100644 index 0000000000..794caa2518 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -0,0 +1,177 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptPropertySet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_assign_op" qualifiers="const"> + <return type="int" enum="VisualScriptPropertySet.AssignOp"> + </return> + <description> + </description> + </method> + <method name="get_base_path" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + </description> + </method> + <method name="get_base_script" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_base_type" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_basic_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="get_call_mode" qualifiers="const"> + <return type="int" enum="VisualScriptPropertySet.CallMode"> + </return> + <description> + </description> + </method> + <method name="get_index" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_property" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_assign_op"> + <return type="void"> + </return> + <argument index="0" name="assign_op" type="int" enum="VisualScriptPropertySet.AssignOp"> + </argument> + <description> + </description> + </method> + <method name="set_base_path"> + <return type="void"> + </return> + <argument index="0" name="base_path" type="NodePath"> + </argument> + <description> + </description> + </method> + <method name="set_base_script"> + <return type="void"> + </return> + <argument index="0" name="base_script" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="base_type" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_basic_type"> + <return type="void"> + </return> + <argument index="0" name="basic_type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + <method name="set_call_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptPropertySet.CallMode"> + </argument> + <description> + </description> + </method> + <method name="set_index"> + <return type="void"> + </return> + <argument index="0" name="index" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_property"> + <return type="void"> + </return> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" enum="VisualScriptPropertySet.AssignOp"> + </member> + <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + </member> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + </member> + <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + </member> + <member name="index" type="String" setter="set_index" getter="get_index"> + </member> + <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + </member> + <member name="property" type="String" setter="set_property" getter="get_property"> + </member> + <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertySet.CallMode"> + </member> + <member name="type_cache" type="Dictionary" setter="_set_type_cache" getter="_get_type_cache"> + </member> + </members> + <constants> + <constant name="CALL_MODE_SELF" value="0"> + </constant> + <constant name="CALL_MODE_NODE_PATH" value="1"> + </constant> + <constant name="CALL_MODE_INSTANCE" value="2"> + </constant> + <constant name="CALL_MODE_BASIC_TYPE" value="3"> + </constant> + <constant name="ASSIGN_OP_NONE" value="0"> + </constant> + <constant name="ASSIGN_OP_ADD" value="1"> + </constant> + <constant name="ASSIGN_OP_SUB" value="2"> + </constant> + <constant name="ASSIGN_OP_MUL" value="3"> + </constant> + <constant name="ASSIGN_OP_DIV" value="4"> + </constant> + <constant name="ASSIGN_OP_MOD" value="5"> + </constant> + <constant name="ASSIGN_OP_SHIFT_LEFT" value="6"> + </constant> + <constant name="ASSIGN_OP_SHIFT_RIGHT" value="7"> + </constant> + <constant name="ASSIGN_OP_BIT_AND" value="8"> + </constant> + <constant name="ASSIGN_OP_BIT_OR" value="9"> + </constant> + <constant name="ASSIGN_OP_BIT_XOR" value="10"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptResourcePath.xml b/modules/visual_script/doc_classes/VisualScriptResourcePath.xml new file mode 100644 index 0000000000..274a852c3e --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptResourcePath.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptResourcePath" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_resource_path"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_resource_path"> + <return type="void"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="path" type="String" setter="set_resource_path" getter="get_resource_path"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptReturn.xml b/modules/visual_script/doc_classes/VisualScriptReturn.xml new file mode 100644 index 0000000000..4ac586a02c --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptReturn.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptReturn" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Exits a function and returns an optional value. + </brief_description> + <description> + Ends the execution of a function and returns control to the calling function. Optionally, it can return a [Variant] value. + [b]Input Ports:[/b] + - Sequence + - Data (variant): [code]result[/code] (optional) + [b]Output Ports:[/b] + none + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_return_type" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="is_return_value_enabled" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_enable_return_value"> + <return type="void"> + </return> + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_return_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled"> + If [code]true[/code] the [code]return[/code] input port is available. + </member> + <member name="return_type" type="int" setter="set_return_type" getter="get_return_type" enum="Variant.Type"> + The return value's data type. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneNode.xml b/modules/visual_script/doc_classes/VisualScriptSceneNode.xml new file mode 100644 index 0000000000..e8fdb69c6a --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSceneNode.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSceneNode" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Node reference. + </brief_description> + <description> + A direct reference to a node. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data: [code]node[/code] (obj) + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_node_path"> + <return type="NodePath"> + </return> + <description> + </description> + </method> + <method name="set_node_path"> + <return type="void"> + </return> + <argument index="0" name="path" type="NodePath"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="node_path" type="NodePath" setter="set_node_path" getter="get_node_path"> + The node's path in the scene tree. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml new file mode 100644 index 0000000000..e74c330623 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSceneTree" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSelect.xml b/modules/visual_script/doc_classes/VisualScriptSelect.xml new file mode 100644 index 0000000000..6a62e364f3 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSelect.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSelect" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Chooses between two input values. + </brief_description> + <description> + Chooses between two input values based on a Boolean condition. + [b]Input Ports:[/b] + - Data (boolean): [code]cond[/code] + - Data (variant): [code]a[/code] + - Data (variant): [code]b[/code] + [b]Output Ports:[/b] + - Data (variant): [code]out[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_typed" qualifiers="const"> + <return type="int" enum="Variant.Type"> + </return> + <description> + </description> + </method> + <method name="set_typed"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Variant.Type"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type"> + The input variables' type. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSelf.xml b/modules/visual_script/doc_classes/VisualScriptSelf.xml new file mode 100644 index 0000000000..f39a02bf84 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSelf.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSelf" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Outputs a reference to the current instance. + </brief_description> + <description> + Provides a reference to the node running the visual script. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (object): [code]instance[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSequence.xml b/modules/visual_script/doc_classes/VisualScriptSequence.xml new file mode 100644 index 0000000000..51238070d5 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSequence.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSequence" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Executes a series of Sequence ports. + </brief_description> + <description> + Steps through a series of one or more output Sequence ports. The [code]current[/code] data port outputs the currently executing item. + [b]Input Ports:[/b] + - Sequence: [code]in order[/code] + [b]Output Ports:[/b] + - Sequence: [code]1[/code] + - Sequence: [code]2 - n[/code] (optional) + - Data (int): [code]current[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_steps" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="set_steps"> + <return type="void"> + </return> + <argument index="0" name="steps" type="int"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="steps" type="int" setter="set_steps" getter="get_steps"> + The number of steps in the sequence. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSubCall.xml b/modules/visual_script/doc_classes/VisualScriptSubCall.xml new file mode 100644 index 0000000000..381095f49b --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSubCall.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSubCall" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="_subcall" qualifiers="virtual"> + <return type="Variant"> + </return> + <argument index="0" name="arguments" type="Variant"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSwitch.xml b/modules/visual_script/doc_classes/VisualScriptSwitch.xml new file mode 100644 index 0000000000..3c8a79f686 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptSwitch.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptSwitch" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Branches program flow based on a given input's value. + </brief_description> + <description> + Branches the flow based on an input's value. Use "Case Count" in the Inspector to set the number of branches and each comparison's optional type. + [b]Input Ports:[/b] + - Sequence: [code]'input' is[/code] + - Data (variant): [code]=[/code] + - Data (variant): [code]=[/code] (optional) + - Data (variant): [code]input[/code] + [b]Output Ports:[/b] + - Sequence + - Sequence (optional) + - Sequence: [code]done[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml new file mode 100644 index 0000000000..417c0a5159 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptTypeCast" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_base_script" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_base_type" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_base_script"> + <return type="void"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="type" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + </member> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml new file mode 100644 index 0000000000..1cad4480a6 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptVariableGet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Gets a variable's value. + </brief_description> + <description> + Returns a variable's value. "Var Name" must be supplied, with an optional type. + [b]Input Ports:[/b] + none + [b]Output Ports:[/b] + - Data (variant): [code]value[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_variable" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_variable"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="var_name" type="String" setter="set_variable" getter="get_variable"> + The variable's name. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml new file mode 100644 index 0000000000..fa3befa21d --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptVariableSet" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Changes a variable's value. + </brief_description> + <description> + Changes a variable's value to the given input. + [b]Input Ports:[/b] + - Sequence + - Data (variant): [code]set[/code] + [b]Output Ports:[/b] + - Sequence + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_variable" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_variable"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="var_name" type="String" setter="set_variable" getter="get_variable"> + The variable's name. + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptWhile.xml b/modules/visual_script/doc_classes/VisualScriptWhile.xml new file mode 100644 index 0000000000..f948660997 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptWhile.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptWhile" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + Conditional loop. + </brief_description> + <description> + Loops while a condition is [code]true[/code]. Execution continues out the [code]exit[/code] Sequence port when the loop terminates. + [b]Input Ports:[/b] + - Sequence: [code]while(cond)[/code] + - Data (bool): [code]cond[/code] + [b]Output Ports:[/b] + - Sequence: [code]repeat[/code] + - Sequence: [code]exit[/code] + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptYield.xml b/modules/visual_script/doc_classes/VisualScriptYield.xml new file mode 100644 index 0000000000..5474ee8b78 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptYield.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptYield" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_wait_time"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="get_yield_mode"> + <return type="int" enum="VisualScriptYield.YieldMode"> + </return> + <description> + </description> + </method> + <method name="set_wait_time"> + <return type="void"> + </return> + <argument index="0" name="sec" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_yield_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptYield.YieldMode"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" enum="VisualScriptYield.YieldMode"> + </member> + <member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time"> + </member> + </members> + <constants> + <constant name="YIELD_FRAME" value="1"> + </constant> + <constant name="YIELD_PHYSICS_FRAME" value="2"> + </constant> + <constant name="YIELD_WAIT" value="3"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml new file mode 100644 index 0000000000..a3b6982075 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptYieldSignal" inherits="VisualScriptNode" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_base_path" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + </description> + </method> + <method name="get_base_type" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_call_mode" qualifiers="const"> + <return type="int" enum="VisualScriptYieldSignal.CallMode"> + </return> + <description> + </description> + </method> + <method name="get_signal" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_base_path"> + <return type="void"> + </return> + <argument index="0" name="base_path" type="NodePath"> + </argument> + <description> + </description> + </method> + <method name="set_base_type"> + <return type="void"> + </return> + <argument index="0" name="base_type" type="String"> + </argument> + <description> + </description> + </method> + <method name="set_call_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="VisualScriptYieldSignal.CallMode"> + </argument> + <description> + </description> + </method> + <method name="set_signal"> + <return type="void"> + </return> + <argument index="0" name="signal" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type"> + </member> + <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptYieldSignal.CallMode"> + </member> + <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + </member> + <member name="signal" type="String" setter="set_signal" getter="get_signal"> + </member> + </members> + <constants> + <constant name="CALL_MODE_SELF" value="0"> + </constant> + <constant name="CALL_MODE_NODE_PATH" value="1"> + </constant> + <constant name="CALL_MODE_INSTANCE" value="2"> + </constant> + </constants> +</class> diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index c50ba17c35..b6ce10381d 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "register_types.h" +#include "core/engine.h" #include "io/resource_loader.h" #include "visual_script.h" #include "visual_script_builtin_funcs.h" @@ -40,6 +41,9 @@ #include "visual_script_yield_nodes.h" VisualScriptLanguage *visual_script_language = NULL; +#ifdef TOOLS_ENABLED +static _VisualScriptEditor *vs_editor_singleton = NULL; +#endif void register_visual_script_types() { @@ -107,6 +111,10 @@ void register_visual_script_types() { register_visual_script_expression_node(); #ifdef TOOLS_ENABLED + ClassDB::register_class<_VisualScriptEditor>(); + vs_editor_singleton = memnew(_VisualScriptEditor); + Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", _VisualScriptEditor::get_singleton())); + VisualScriptEditor::register_editor(); #endif } @@ -119,6 +127,9 @@ void unregister_visual_script_types() { #ifdef TOOLS_ENABLED VisualScriptEditor::free_clipboard(); + if (vs_editor_singleton) { + memdelete(vs_editor_singleton); + } #endif if (visual_script_language) memdelete(visual_script_language); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 765fe4c2f2..0834bc81d9 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -2644,6 +2644,11 @@ void VisualScriptLanguage::add_register_func(const String &p_name, VisualScriptN register_funcs[p_name] = p_func; } +void VisualScriptLanguage::remove_register_func(const String &p_name) { + ERR_FAIL_COND(!register_funcs.has(p_name)); + register_funcs.erase(p_name); +} + Ref<VisualScriptNode> VisualScriptLanguage::create_node_from_name(const String &p_name) { ERR_FAIL_COND_V(!register_funcs.has(p_name), Ref<VisualScriptNode>()); diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 0f60b103c9..3e31876941 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -600,6 +600,7 @@ public: virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max); void add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func); + void remove_register_func(const String &p_name); Ref<VisualScriptNode> create_node_from_name(const String &p_name); void get_registered_node_names(List<String> *r_names); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 03015df844..86cf5b27e6 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "visual_script_editor.h" +#include "core/script_language.h" #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "os/input.h" @@ -2764,6 +2765,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(); @@ -3241,6 +3259,8 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_member_rmb_selected", &VisualScriptEditor::_member_rmb_selected); ClassDB::bind_method("_member_option", &VisualScriptEditor::_member_option); + + ClassDB::bind_method("_update_available_nodes", &VisualScriptEditor::_update_available_nodes); } VisualScriptEditor::VisualScriptEditor() { @@ -3425,6 +3445,8 @@ VisualScriptEditor::VisualScriptEditor() { members->connect("item_rmb_selected", this, "_member_rmb_selected"); members->set_allow_rmb_select(true); member_popup->connect("id_pressed", this, "_member_option"); + + _VisualScriptEditor::get_singleton()->connect("custom_nodes_updated", this, "_update_available_nodes"); } VisualScriptEditor::~VisualScriptEditor() { @@ -3468,4 +3490,42 @@ void VisualScriptEditor::register_editor() { EditorNode::add_plugin_init_callback(register_editor_callback); } +Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_name) { + + Ref<VisualScriptCustomNode> node; + node.instance(); + node->set_script(singleton->custom_nodes[p_name]); + return node; +} + +_VisualScriptEditor *_VisualScriptEditor::singleton = NULL; +Map<String, RefPtr> _VisualScriptEditor::custom_nodes; + +_VisualScriptEditor::_VisualScriptEditor() { + singleton = this; +} + +_VisualScriptEditor::~_VisualScriptEditor() { + custom_nodes.clear(); +} + +void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { + String node_name = "custom/" + p_category + "/" + p_name; + custom_nodes.insert(node_name, p_script.get_ref_ptr()); + VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom); + emit_signal("custom_nodes_updated"); +} + +void _VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) { + String node_name = "custom/" + p_category + "/" + p_name; + custom_nodes.erase(node_name); + VisualScriptLanguage::singleton->remove_register_func(node_name); + emit_signal("custom_nodes_updated"); +} + +void _VisualScriptEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &_VisualScriptEditor::add_custom_node); + ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &_VisualScriptEditor::remove_custom_node); + ADD_SIGNAL(MethodInfo("custom_nodes_updated")); +} #endif diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index db54d10300..3d037e82ea 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -278,6 +278,29 @@ public: VisualScriptEditor(); ~VisualScriptEditor(); }; + +// Singleton +class _VisualScriptEditor : public Object { + GDCLASS(_VisualScriptEditor, Object); + + friend class VisualScriptLanguage; + +protected: + static void _bind_methods(); + static _VisualScriptEditor *singleton; + + static Map<String, RefPtr> custom_nodes; + static Ref<VisualScriptNode> create_node_custom(const String &p_name); + +public: + static _VisualScriptEditor *get_singleton() { return singleton; } + + void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script); + void remove_custom_node(const String &p_name, const String &p_category); + + _VisualScriptEditor(); + ~_VisualScriptEditor(); +}; #endif #endif // VISUALSCRIPT_EDITOR_H 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..cbe4438cdf 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ #include "visual_script_func_nodes.h" +#include "engine.h" #include "io/resource_loader.h" #include "os/os.h" -#include "project_settings.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" #include "visual_script_nodes.h" @@ -344,7 +344,7 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_type) { return; singleton = p_type; - Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton); + Object *obj = Engine::get_singleton()->get_singleton_object(singleton); if (obj) { base_type = obj->get_class(); } @@ -380,7 +380,7 @@ void VisualScriptFunctionCall::_update_method_cache() { } else if (call_mode == CALL_MODE_SINGLETON) { - Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton); + Object *obj = Engine::get_singleton()->get_singleton_object(singleton); if (obj) { type = obj->get_class(); script = obj->get_script(); @@ -565,11 +565,11 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const if (call_mode != CALL_MODE_SINGLETON) { property.usage = 0; } else { - List<ProjectSettings::Singleton> names; - ProjectSettings::get_singleton()->get_singletons(&names); + List<Engine::Singleton> names; + Engine::get_singleton()->get_singletons(&names); property.hint = PROPERTY_HINT_ENUM; String sl; - for (List<ProjectSettings::Singleton>::Element *E = names.front(); E; E = E->next()) { + for (List<Engine::Singleton>::Element *E = names.front(); E; E = E->next()) { if (sl != String()) sl += ","; sl += E->get().name; @@ -603,7 +603,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const property.hint_string = itos(get_visual_script()->get_instance_id()); } else if (call_mode == CALL_MODE_SINGLETON) { - Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton); + Object *obj = Engine::get_singleton()->get_singleton_object(singleton); if (obj) { property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE; property.hint_string = itos(obj->get_instance_id()); @@ -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"; @@ -877,7 +879,7 @@ public: } break; case VisualScriptFunctionCall::CALL_MODE_SINGLETON: { - Object *object = ProjectSettings::get_singleton()->get_singleton_object(singleton); + Object *object = Engine::get_singleton()->get_singleton_object(singleton); if (!object) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; r_error_str = "Invalid singleton name: '" + String(singleton) + "'"; diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index d3cd839cf3..05ff629d1b 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "visual_script_nodes.h" +#include "engine.h" #include "global_constants.h" #include "os/input.h" #include "os/os.h" @@ -1776,8 +1777,8 @@ VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() { const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = { "One", "PI", - "PIx2", "PI/2", + "TAU", "E", "Sqrt2", "INF", @@ -1787,8 +1788,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, @@ -1886,8 +1887,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); @@ -1976,13 +1977,13 @@ public: VisualScriptNodeInstance *VisualScriptEngineSingleton::instance(VisualScriptInstance *p_instance) { VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton); - instance->singleton = ProjectSettings::get_singleton()->get_singleton_object(singleton); + instance->singleton = Engine::get_singleton()->get_singleton_object(singleton); return instance; } VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const { - Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton); + Object *obj = Engine::get_singleton()->get_singleton_object(singleton); TypeGuess tg; tg.type = Variant::OBJECT; if (obj) { @@ -2000,11 +2001,11 @@ void VisualScriptEngineSingleton::_bind_methods() { String cc; - List<ProjectSettings::Singleton> singletons; + List<Engine::Singleton> singletons; - ProjectSettings::get_singleton()->get_singletons(&singletons); + Engine::get_singleton()->get_singletons(&singletons); - for (List<ProjectSettings::Singleton>::Element *E = singletons.front(); E; E = E->next()) { + for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D") continue; //skip these, too simple named 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/vorbis/SCsub b/modules/vorbis/SCsub index 9d2d0feb92..55a112585b 100644 --- a/modules/vorbis/SCsub +++ b/modules/vorbis/SCsub @@ -5,6 +5,8 @@ Import('env_modules') env_vorbis = env_modules.Clone() +stub = True + # Thirdparty source files if env['builtin_libvorbis']: thirdparty_dir = "#thirdparty/libvorbis/" @@ -45,5 +47,9 @@ if env['builtin_libvorbis']: if env['builtin_libogg']: env_vorbis.Append(CPPPATH=["#thirdparty/libogg"]) -# Godot source files -env_vorbis.add_source_files(env.modules_sources, "*.cpp") +if not stub: + # Module files + env_vorbis.add_source_files(env.modules_sources, "*.cpp") +else: + # Module files + env_vorbis.add_source_files(env.modules_sources, "stub/register_types.cpp") diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index 6235799fc2..9fb6fa8197 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -106,8 +106,6 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) { break; } -//printf("to mix %i - mix me %i bytes\n",to_mix,to_mix*stream_channels*sizeof(int16_t)); - #ifdef BIG_ENDIAN_ENABLED long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 1, 2, 1, ¤t_section); #else @@ -359,7 +357,7 @@ void AudioStreamPlaybackOGGVorbis::set_paused(bool p_paused) { paused = p_paused; } -bool AudioStreamPlaybackOGGVorbis::is_paused(bool p_paused) const { +bool AudioStreamPlaybackOGGVorbis::is_paused() const { return paused; } diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h index 79eadec56e..5000d03fd4 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.h +++ b/modules/vorbis/audio_stream_ogg_vorbis.h @@ -85,7 +85,7 @@ public: virtual void set_loop_restart_time(float p_time) { loop_restart_time = p_time; } virtual void set_paused(bool p_paused); - virtual bool is_paused(bool p_paused) const; + virtual bool is_paused() const; virtual void set_loop(bool p_enable); virtual bool has_loop() const; diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py index ef5daca05c..5f133eba90 100644 --- a/modules/vorbis/config.py +++ b/modules/vorbis/config.py @@ -1,8 +1,5 @@ - def can_build(platform): -# return True - return False - + return True def configure(env): pass diff --git a/modules/vorbis/stub/register_types.cpp b/modules/vorbis/stub/register_types.cpp new file mode 100644 index 0000000000..b93d890436 --- /dev/null +++ b/modules/vorbis/stub/register_types.cpp @@ -0,0 +1,36 @@ +/*************************************************************************/ +/* 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" + +// Dummy module as libvorbis is needed by other modules (theora ...) + +void register_vorbis_types() {} + +void unregister_vorbis_types() {} diff --git a/modules/vorbis/stub/register_types.h b/modules/vorbis/stub/register_types.h new file mode 100644 index 0000000000..e7cde7a66c --- /dev/null +++ b/modules/vorbis/stub/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_vorbis_types(); +void unregister_vorbis_types(); diff --git a/modules/webm/config.py b/modules/webm/config.py index ef5daca05c..0374bb36f7 100644 --- a/modules/webm/config.py +++ b/modules/webm/config.py @@ -1,8 +1,14 @@ - def can_build(platform): -# return True - return False - + return True def configure(env): pass + +def get_doc_classes(): + return [ + "ResourceImporterWebm", + "VideoStreamWebm", + ] + +def get_doc_path(): + return "doc_classes" diff --git a/modules/webm/doc_classes/ResourceImporterWebm.xml b/modules/webm/doc_classes/ResourceImporterWebm.xml new file mode 100644 index 0000000000..dcba351e37 --- /dev/null +++ b/modules/webm/doc_classes/ResourceImporterWebm.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ResourceImporterWebm" inherits="ResourceImporter" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/webm/doc_classes/VideoStreamWebm.xml b/modules/webm/doc_classes/VideoStreamWebm.xml new file mode 100644 index 0000000000..9a430f6b0d --- /dev/null +++ b/modules/webm/doc_classes/VideoStreamWebm.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VideoStreamWebm" inherits="VideoStream" category="Core" version="3.0-alpha"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_file"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="set_file"> + <return type="void"> + </return> + <argument index="0" name="file" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="file" type="String" setter="set_file" getter="get_file"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub index fd8d762a5e..73ba17d184 100644 --- a/modules/webm/libvpx/SCsub +++ b/modules/webm/libvpx/SCsub @@ -298,7 +298,7 @@ if webm_cpu_x86: if not yasm_found: webm_cpu_x86 = False - print "YASM is necessary for WebM SIMD optimizations." + print("YASM is necessary for WebM SIMD optimizations.") webm_simd_optimizations = False @@ -345,7 +345,7 @@ if webm_cpu_arm: webm_simd_optimizations = True if webm_simd_optimizations == False: - print "WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!" + print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!") env_libvpx.add_source_files(env.modules_sources, libvpx_sources) diff --git a/modules/webm/register_types.cpp b/modules/webm/register_types.cpp index 892d1b8420..669c9997f1 100644 --- a/modules/webm/register_types.cpp +++ b/modules/webm/register_types.cpp @@ -28,19 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" - +#include "resource_importer_webm.h" #include "video_stream_webm.h" -static ResourceFormatLoaderVideoStreamWebm *webm_stream_loader = NULL; - void register_webm_types() { - webm_stream_loader = memnew(ResourceFormatLoaderVideoStreamWebm); - ResourceLoader::add_resource_format_loader(webm_stream_loader); +#ifdef TOOLS_ENABLED + Ref<ResourceImporterWebm> webm_import; + webm_import.instance(); + ResourceFormatImporter::get_singleton()->add_importer(webm_import); +#endif ClassDB::register_class<VideoStreamWebm>(); } void unregister_webm_types() { - - memdelete(webm_stream_loader); } diff --git a/modules/webm/resource_importer_webm.cpp b/modules/webm/resource_importer_webm.cpp new file mode 100644 index 0000000000..5db3d4df2e --- /dev/null +++ b/modules/webm/resource_importer_webm.cpp @@ -0,0 +1,95 @@ +/*************************************************************************/ +/* resource_importer_webm.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 "resource_importer_webm.h" + +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "scene/resources/texture.h" +#include "video_stream_webm.h" + +String ResourceImporterWebm::get_importer_name() const { + + return "Webm"; +} + +String ResourceImporterWebm::get_visible_name() const { + + return "Webm"; +} +void ResourceImporterWebm::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("webm"); +} + +String ResourceImporterWebm::get_save_extension() const { + return "webmstr"; +} + +String ResourceImporterWebm::get_resource_type() const { + + return "VideoStreamWebm"; +} + +bool ResourceImporterWebm::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + + return true; +} + +int ResourceImporterWebm::get_preset_count() const { + return 0; +} +String ResourceImporterWebm::get_preset_name(int p_idx) const { + + return String(); +} + +void ResourceImporterWebm::get_import_options(List<ImportOption> *r_options, int p_preset) const { + + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); +} + +Error ResourceImporterWebm::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { + + FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); + if (!f) { + ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + } + memdelete(f); + + VideoStreamWebm *stream = memnew(VideoStreamWebm); + stream->set_file(p_source_file); + + Ref<VideoStreamWebm> webm_stream = Ref<VideoStreamWebm>(stream); + + return ResourceSaver::save(p_save_path + ".webmstr", webm_stream); +} + +ResourceImporterWebm::ResourceImporterWebm() { +} diff --git a/modules/webm/resource_importer_webm.h b/modules/webm/resource_importer_webm.h new file mode 100644 index 0000000000..4cedd1598d --- /dev/null +++ b/modules/webm/resource_importer_webm.h @@ -0,0 +1,55 @@ +/*************************************************************************/ +/* resource_importer_webm.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 RESOURCEIMPORTERWEBM_H +#define RESOURCEIMPORTERWEBM_H + +#include "io/resource_import.h" + +class ResourceImporterWebm : public ResourceImporter { + GDCLASS(ResourceImporterWebm, ResourceImporter) +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + + ResourceImporterWebm(); +}; + +#endif // RESOURCEIMPORTERWEBM_H diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 2ec6b27471..0fc9df5b58 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -35,10 +35,13 @@ #include "mkvparser/mkvparser.h" #include "os/file_access.h" +#include "os/os.h" #include "project_settings.h" #include "thirdparty/misc/yuv2rgb.h" +#include "servers/audio_server.h" + #include <string.h> class MkvReader : public mkvparser::IMkvReader { @@ -47,6 +50,8 @@ public: MkvReader(const String &p_file) { file = FileAccess::open(p_file, FileAccess::READ); + + ERR_EXPLAIN("Failed loading resource: '" + p_file + "';"); ERR_FAIL_COND(!file); } ~MkvReader() { @@ -113,14 +118,14 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) { webm = memnew(WebMDemuxer(new MkvReader(file_name), 0, audio_track)); if (webm->isOpen()) { - video = memnew(VPXDecoder(*webm, 8)); //TODO: Detect CPU threads + video = memnew(VPXDecoder(*webm, OS::get_singleton()->get_processor_count())); if (video->isOpen()) { audio = memnew(OpusVorbisDecoder(*webm)); if (audio->isOpen()) { audio_frame = memnew(WebMFrame); - pcm = (int16_t *)memalloc(sizeof(int16_t) * audio->getBufferSamples() * webm->getChannels()); + pcm = (float *)memalloc(sizeof(float) * audio->getBufferSamples() * webm->getChannels()); } else { memdelete(audio); @@ -183,7 +188,7 @@ void VideoStreamPlaybackWebm::set_paused(bool p_paused) { paused = p_paused; } -bool VideoStreamPlaybackWebm::is_paused(bool p_paused) const { +bool VideoStreamPlaybackWebm::is_paused() const { return paused; } @@ -222,11 +227,18 @@ Ref<Texture> VideoStreamPlaybackWebm::get_texture() { return texture; } + void VideoStreamPlaybackWebm::update(float p_delta) { if ((!playing || paused) || !video) return; + time += p_delta; + + if (time < video_pos) { + return; + } + bool audio_buffer_full = false; if (samples_offset > -1) { @@ -245,13 +257,15 @@ void VideoStreamPlaybackWebm::update(float p_delta) { } const bool hasAudio = (audio && mix_callback); - while ((hasAudio && (!audio_buffer_full || !has_enough_video_frames())) || (!hasAudio && video_frames_pos == 0)) { + while ((hasAudio && !audio_buffer_full && !has_enough_video_frames()) || + (!hasAudio && video_frames_pos == 0)) { - if (hasAudio && !audio_buffer_full && audio_frame->isValid() && audio->getPCMS16(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) { + if (hasAudio && !audio_buffer_full && audio_frame->isValid() && + audio->getPCMF(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) { const int mixed = mix_callback(mix_udata, pcm, num_decoded_samples); - if (mixed != num_decoded_samples) { + if (mixed != num_decoded_samples) { samples_offset = mixed; audio_buffer_full = true; } @@ -273,72 +287,61 @@ void VideoStreamPlaybackWebm::update(float p_delta) { ++video_frames_pos; }; - const double video_delay = video->getFramesDelay() * video_frame_delay; - - bool want_this_frame = false; - while (video_frames_pos > 0 && !want_this_frame) { + bool video_frame_done = false; + while (video_frames_pos > 0 && !video_frame_done) { WebMFrame *video_frame = video_frames[0]; - if (video_frame->time <= time + video_delay) { - if (video->decode(*video_frame)) { + // It seems VPXDecoder::decode has to be executed even though we might skip this frame + if (video->decode(*video_frame)) { - VPXDecoder::IMAGE_ERROR err; - VPXDecoder::Image image; + VPXDecoder::IMAGE_ERROR err; + VPXDecoder::Image image; - while ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) { + if (should_process(*video_frame)) { - want_this_frame = (time - video_frame->time <= video_frame_delay); + if ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) { - if (want_this_frame) { + if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) { - if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) { + PoolVector<uint8_t>::Write w = frame_data.write(); + bool converted = false; - PoolVector<uint8_t>::Write w = frame_data.write(); - bool converted = false; + if (image.chromaShiftW == 1 && image.chromaShiftH == 1) { - if (image.chromaShiftW == 1 && image.chromaShiftH == 1) { + yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + // libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); + converted = true; + } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) { - yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); - // libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) { + yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + // libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); + converted = true; + } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) { - yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); - // libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) { + yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + // libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); + converted = true; + } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) { - yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); - // libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) { - - // libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - // converted = true; - } - - if (converted) - texture->set_data(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); //Zero copy send to visual server + // libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); + // converted = true; } - break; + if (converted) { + Ref<Image> img = memnew(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); + texture->set_data(img); //Zero copy send to visual server + video_frame_done = true; + } } } } - - video_frame_delay = video_frame->time - video_pos; - video_pos = video_frame->time; - - memmove(video_frames, video_frames + 1, (--video_frames_pos) * sizeof(void *)); - video_frames[video_frames_pos] = video_frame; - } else { - - break; } - } - time += p_delta; + video_pos = video_frame->time; + memmove(video_frames, video_frames + 1, (--video_frames_pos) * sizeof(void *)); + video_frames[video_frames_pos] = video_frame; + } if (video_frames_pos == 0 && webm->isEOS()) stop(); @@ -372,6 +375,11 @@ inline bool VideoStreamPlaybackWebm::has_enough_video_frames() const { return false; } +bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) { + const double audio_delay = AudioServer::get_singleton()->get_output_delay(); + return video_frame.time >= time + audio_delay + delay_compensation; +} + void VideoStreamPlaybackWebm::delete_pointers() { if (pcm) @@ -395,34 +403,6 @@ void VideoStreamPlaybackWebm::delete_pointers() { /**/ -RES ResourceFormatLoaderVideoStreamWebm::load(const String &p_path, const String &p_original_path, Error *r_error) { - - Ref<VideoStreamWebm> stream = memnew(VideoStreamWebm); - stream->set_file(p_path); - if (r_error) - *r_error = OK; - return stream; -} - -void ResourceFormatLoaderVideoStreamWebm::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("webm"); -} -bool ResourceFormatLoaderVideoStreamWebm::handles_type(const String &p_type) const { - - return (p_type == "VideoStream" || p_type == "VideoStreamWebm"); -} - -String ResourceFormatLoaderVideoStreamWebm::get_resource_type(const String &p_path) const { - - const String exl = p_path.get_extension().to_lower(); - if (exl == "webm") - return "VideoStreamWebm"; - return ""; -} - -/**/ - VideoStreamWebm::VideoStreamWebm() : audio_track(0) {} @@ -439,6 +419,19 @@ void VideoStreamWebm::set_file(const String &p_file) { file = p_file; } +String VideoStreamWebm::get_file() { + + return file; +} + +void VideoStreamWebm::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamWebm::set_file); + ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamWebm::get_file); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file"); +} + void VideoStreamWebm::set_audio_track(int p_track) { audio_track = p_track; diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index fc0720967a..f7dd16a38f 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -60,7 +60,7 @@ class VideoStreamPlaybackWebm : public VideoStreamPlayback { PoolVector<uint8_t> frame_data; Ref<ImageTexture> texture; - int16_t *pcm; + float *pcm; public: VideoStreamPlaybackWebm(); @@ -74,7 +74,7 @@ public: virtual bool is_playing() const; virtual void set_paused(bool p_paused); - virtual bool is_paused(bool p_paused) const; + virtual bool is_paused() const; virtual void set_loop(bool p_enable); virtual bool has_loop() const; @@ -95,6 +95,7 @@ public: private: inline bool has_enough_video_frames() const; + bool should_process(WebMFrame &video_frame); void delete_pointers(); }; @@ -103,27 +104,21 @@ private: class VideoStreamWebm : public VideoStream { - GDCLASS(VideoStreamWebm, VideoStream) + GDCLASS(VideoStreamWebm, VideoStream); + RES_BASE_EXTENSION("webmstr"); String file; int audio_track; +protected: + static void _bind_methods(); + public: VideoStreamWebm(); virtual Ref<VideoStreamPlayback> instance_playback(); virtual void set_file(const String &p_file); + String get_file(); virtual void set_audio_track(int p_track); }; - -/**/ - -class ResourceFormatLoaderVideoStreamWebm : public ResourceFormatLoader { - -public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error); - 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; -}; diff --git a/modules/webp/config.py b/modules/webp/config.py index fb920482f5..5f133eba90 100644 --- a/modules/webp/config.py +++ b/modules/webp/config.py @@ -1,7 +1,5 @@ - def can_build(platform): return True - def configure(env): pass |
