summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bullet/godot_collision_configuration.cpp56
-rw-r--r--modules/bullet/godot_collision_configuration.h13
-rw-r--r--modules/bullet/godot_result_callbacks.cpp8
-rw-r--r--modules/bullet/rigid_body_bullet.cpp5
-rw-r--r--modules/bullet/space_bullet.cpp59
-rw-r--r--modules/bullet/space_bullet.h2
-rw-r--r--modules/gdnative/arvr/config.py2
-rw-r--r--modules/gdscript/gdscript.cpp5
-rw-r--r--modules/gdscript/gdscript_compiler.cpp16
-rw-r--r--modules/gdscript/gdscript_editor.cpp15
-rw-r--r--modules/gdscript/gdscript_functions.cpp2
-rw-r--r--modules/gdscript/gdscript_parser.cpp48
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp2
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.cpp47
-rw-r--r--modules/mono/SCsub1
-rw-r--r--modules/mono/config.py26
-rw-r--r--modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs105
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj1
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs14
-rw-r--r--modules/mono/editor/GodotSharpTools/Utils/OS.cs62
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp27
-rw-r--r--modules/mono/editor/godotsharp_builds.h5
-rw-r--r--modules/mono/editor/godotsharp_editor.cpp125
-rw-r--r--modules/mono/editor/godotsharp_editor.h19
-rw-r--r--modules/mono/editor/monodevelop_instance.cpp11
-rw-r--r--modules/mono/editor/monodevelop_instance.h7
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs32
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs19
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp2
-rw-r--r--modules/mono/utils/osx_utils.cpp62
-rw-r--r--modules/mono/utils/osx_utils.h41
-rw-r--r--modules/opensimplex/doc_classes/SimplexNoise.xml39
-rw-r--r--modules/opensimplex/simplex_noise.cpp20
-rw-r--r--modules/opensimplex/simplex_noise.h6
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp7
35 files changed, 757 insertions, 154 deletions
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
index f4bb9acbd7..919c3152d7 100644
--- a/modules/bullet/godot_collision_configuration.cpp
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -94,3 +94,59 @@ btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getClosestPointsAlg
return btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1);
}
}
+
+GodotSoftCollisionConfiguration::GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
+ btSoftBodyRigidBodyCollisionConfiguration(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);
+}
+
+GodotSoftCollisionConfiguration::~GodotSoftCollisionConfiguration() {
+ m_rayWorldCF->~btCollisionAlgorithmCreateFunc();
+ btAlignedFree(m_rayWorldCF);
+
+ m_swappedRayWorldCF->~btCollisionAlgorithmCreateFunc();
+ btAlignedFree(m_swappedRayWorldCF);
+}
+
+btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) {
+
+ if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
+
+ // This collision is not supported
+ return m_emptyCreateFunc;
+ } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
+
+ return m_rayWorldCF;
+ } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
+
+ return m_swappedRayWorldCF;
+ } else {
+
+ return btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1);
+ }
+}
+
+btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) {
+
+ if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
+
+ // This collision is not supported
+ return m_emptyCreateFunc;
+ } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
+
+ return m_rayWorldCF;
+ } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
+
+ return m_swappedRayWorldCF;
+ } else {
+
+ return btSoftBodyRigidBodyCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1);
+ }
+}
diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h
index 9b30ad0c62..11012c5f6d 100644
--- a/modules/bullet/godot_collision_configuration.h
+++ b/modules/bullet/godot_collision_configuration.h
@@ -32,6 +32,7 @@
#define GODOT_COLLISION_CONFIGURATION_H
#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
+#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h>
/**
@author AndreaCatania
@@ -50,4 +51,16 @@ public:
virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1);
virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1);
};
+
+class GodotSoftCollisionConfiguration : public btSoftBodyRigidBodyCollisionConfiguration {
+ btCollisionAlgorithmCreateFunc *m_rayWorldCF;
+ btCollisionAlgorithmCreateFunc *m_swappedRayWorldCF;
+
+public:
+ GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo = btDefaultCollisionConstructionInfo());
+ virtual ~GodotSoftCollisionConfiguration();
+
+ virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1);
+ virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1);
+};
#endif
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 08d8b8c6f6..3b44ab838e 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -164,9 +164,11 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
}
btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
- m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
- return res;
+ if (convexResult.m_localShapeInfo)
+ m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ else
+ m_shapeId = 0;
+ return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
}
bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index f81cfe84fb..f24c8670a3 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -351,7 +351,7 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
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() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) {
+ if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) {
if (omit_forces_integration)
btBody->clearForces();
@@ -774,10 +774,13 @@ Vector3 RigidBodyBullet::get_angular_velocity() const {
void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) {
if (mode == PhysicsServer::BODY_MODE_KINEMATIC) {
+ if (space)
+ btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time());
// The kinematic use MotionState class
godotMotionState->moveBody(p_global_transform);
}
btBody->setWorldTransform(p_global_transform);
+ scratch();
}
const btTransform &RigidBodyBullet::get_transform__bullet() const {
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 5b220e1039..329e12cfff 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -150,14 +150,14 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
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_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
+bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
- return 0;
+ return false;
}
btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape);
@@ -177,10 +177,13 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002);
+ r_closest_unsafe = 1.0;
+ r_closest_safe = 1.0;
+
if (btResult.hasHit()) {
const btScalar l = bt_motion.length();
- p_closest_unsafe = btResult.m_closestHitFraction;
- p_closest_safe = MAX(p_closest_unsafe - (1 - ((l - 0.01) / l)), 0);
+ r_closest_unsafe = btResult.m_closestHitFraction;
+ r_closest_safe = MAX(r_closest_unsafe - (1 - ((l - 0.01) / l)), 0);
if (r_info) {
if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) {
B_TO_G(static_cast<const btRigidBody *>(btResult.m_hitCollisionObject)->getVelocityInLocalPoint(btResult.m_hitPointWorld), r_info->linear_velocity);
@@ -195,7 +198,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
}
bulletdelete(bt_convex_shape);
- return btResult.hasHit();
+ return true; // Mean success
}
/// Returns the list of contacts pairs in this order: Local contact, other body contact
@@ -577,7 +580,7 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
}
if (p_create_soft_world) {
- collisionConfiguration = bulletnew(btSoftBodyRigidBodyCollisionConfiguration);
+ collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
} else {
collisionConfiguration = bulletnew(GodotCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
}
@@ -786,30 +789,32 @@ void SpaceBullet::check_body_collision() {
if (numContacts) {
btManifoldPoint &pt = contactManifold->getContactPoint(0);
#endif
- Vector3 collisionWorldPosition;
- Vector3 collisionLocalPosition;
- Vector3 normalOnB;
- float appliedImpulse = pt.m_appliedImpulse;
- 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, appliedImpulse, 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, appliedImpulse * -1, pt.m_index0, pt.m_index1);
- }
+ if (pt.getDistance() <= 0.0) {
+ Vector3 collisionWorldPosition;
+ Vector3 collisionLocalPosition;
+ Vector3 normalOnB;
+ float appliedImpulse = pt.m_appliedImpulse;
+ 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, appliedImpulse, 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, appliedImpulse * -1, pt.m_index0, pt.m_index1);
+ }
#ifdef DEBUG_ENABLED
- if (is_debugging_contacts()) {
- add_debug_contact(collisionWorldPosition);
- }
+ if (is_debugging_contacts()) {
+ add_debug_contact(collisionWorldPosition);
+ }
#endif
+ }
}
}
}
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 0649e1f7e3..67ab5c610d 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -78,7 +78,7 @@ public:
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
- 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL);
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
diff --git a/modules/gdnative/arvr/config.py b/modules/gdnative/arvr/config.py
index 4d1bdfe4d1..53bc827027 100644
--- a/modules/gdnative/arvr/config.py
+++ b/modules/gdnative/arvr/config.py
@@ -1,4 +1,4 @@
-def can_build(platform):
+def can_build(env, platform):
return True
def configure(env):
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index d12c1f555c..b0d5422afe 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -126,10 +126,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
GDScriptLanguage::singleton->lock->unlock();
#endif
- if (r_error.error != Variant::CallError::CALL_OK) {
- memdelete(instance);
- ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
- }
+ ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
}
//@TODO make thread safe
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 741b837b05..310c4e21f2 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -388,7 +388,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int ret = _parse_expression(codegen, an->elements[i], slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -419,7 +419,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int ret = _parse_expression(codegen, dn->elements[i].key, slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -429,7 +429,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
ret = _parse_expression(codegen, dn->elements[i].value, slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -545,7 +545,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int ret = _parse_expression(codegen, on->arguments[i], slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -578,7 +578,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int ret = _parse_expression(codegen, on->arguments[i], slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -606,7 +606,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -655,7 +655,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
ret = _parse_expression(codegen, on->arguments[i], slevel);
if (ret < 0)
return ret;
- if (ret & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
@@ -681,7 +681,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int ret = _parse_expression(codegen, on->arguments[i], slevel);
if (ret < 0)
return ret;
- if (ret & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) {
+ if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
}
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 32a7668760..a9b641de50 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -1189,6 +1189,7 @@ static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, c
c.line = op->line;
c.block = blk;
if (_guess_expression_type(p_context, op->arguments[1], r_type)) {
+ r_type.type.is_meta_type = false;
return true;
}
}
@@ -1221,7 +1222,7 @@ static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, c
int def_from = p_context.function->arguments.size() - p_context.function->default_values.size();
if (i >= def_from) {
- int def_idx = def_from - i;
+ int def_idx = i - def_from;
if (p_context.function->default_values[def_idx]->type == GDScriptParser::Node::TYPE_OPERATOR) {
const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_context.function->default_values[def_idx]);
if (op->arguments.size() < 2) {
@@ -1376,11 +1377,11 @@ static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_
for (int i = 0; i < base_type.class_type->variables.size(); i++) {
GDScriptParser::ClassNode::Member m = base_type.class_type->variables[i];
if (m.identifier == p_identifier) {
- if (m.data_type.has_type) {
- r_type.type = m.data_type;
- return true;
- }
if (m.expression) {
+ if (p_context.line == m.expression->line) {
+ // Variable used in the same expression
+ return false;
+ }
if (_guess_expression_type(p_context, m.expression, r_type)) {
return true;
}
@@ -1389,6 +1390,10 @@ static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_
return true;
}
}
+ if (m.data_type.has_type) {
+ r_type.type = m.data_type;
+ return true;
+ }
return false;
}
}
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index c469defb01..5af9bbc05f 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -1458,7 +1458,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_ATAN2: {
- MethodInfo mi("atan2", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y"));
+ MethodInfo mi("atan2", PropertyInfo(Variant::REAL, "y"), PropertyInfo(Variant::REAL, "x"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 89e102a858..ea1287374b 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -81,8 +81,11 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
}
tokenizer->advance();
- if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
+ return false;
+ }
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
// be more python-like
int current = tab_level.back()->get();
tab_level.push_back(current);
@@ -92,10 +95,11 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
}
while (true) {
-
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
return false; //wtf
+ } else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) {
+ return false;
} else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
int indent = tokenizer->get_token_line_indent();
@@ -637,9 +641,21 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = op;
} else {
-
- _set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
- return NULL;
+ // Object is a special case
+ bool valid = false;
+ if (bi_type == Variant::OBJECT) {
+ int object_constant = ClassDB::get_integer_constant("Object", identifier, &valid);
+ if (valid) {
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->value = object_constant;
+ cn->datatype = _type_from_variant(cn->value);
+ expr = cn;
+ }
+ }
+ if (!valid) {
+ _set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
+ return NULL;
+ }
}
} else {
@@ -4443,7 +4459,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_SLAVE:
+#ifdef DEBUG_ENABLED
_add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet");
+#endif
case GDScriptTokenizer::TK_PR_PUPPET: {
//may be fallthrough from export, ignore if so
@@ -4849,6 +4867,20 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
StringName const_id = tokenizer->get_token_literal();
+ if (current_class->constant_expressions.has(const_id)) {
+ _set_error("A constant named '" + String(const_id) + "' already exists in this class (at line: " +
+ itos(current_class->constant_expressions[const_id].expression->line) + ").");
+ return;
+ }
+
+ for (int i = 0; i < current_class->variables.size(); i++) {
+ if (current_class->variables[i].identifier == const_id) {
+ _set_error("A variable named '" + String(const_id) + "' already exists in this class (at line: " +
+ itos(current_class->variables[i].line) + ").");
+ return;
+ }
+ }
+
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
@@ -7202,6 +7234,12 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
expr.is_constant = true;
c.type = expr;
c.expression->set_datatype(expr);
+
+ DataType tmp;
+ if (_get_member_type(p_class->base_type, E->key(), tmp)) {
+ _set_error("Member '" + String(E->key()) + "' already exists in parent class.", c.expression->line);
+ return;
+ }
}
// Function declarations
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index e6eaabd9ce..5fdb6a5196 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -645,7 +645,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
}
set_items.clear();
input_action = INPUT_NONE;
- return true;
+ return set_items.size() > 0;
}
if (mb->get_button_index() == BUTTON_LEFT && input_action != INPUT_NONE) {
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp
index 3398957775..e0cd67a810 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbed_tls.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "stream_peer_mbed_tls.h"
+#include "core/io/stream_peer_tcp.h"
#include "core/os/file_access.h"
#include "mbedtls/platform_util.h"
@@ -98,12 +99,16 @@ Error StreamPeerMbedTLS::_do_handshake() {
int ret = 0;
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ // An error occurred.
ERR_PRINTS("TLS handshake error: " + itos(ret));
_print_error(ret);
disconnect_from_stream();
status = STATUS_ERROR;
return FAILED;
- } else if (!blocking_handshake) {
+ }
+
+ // Handshake is still in progress.
+ if (!blocking_handshake) {
// Will retry via poll later
return OK;
}
@@ -192,7 +197,12 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in
int ret = mbedtls_ssl_write(&ssl, p_data, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
- ret = 0; // non blocking io
+ // Non blocking IO
+ ret = 0;
+ } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ // Clean close
+ disconnect_from_stream();
+ return ERR_FILE_EOF;
} else if (ret <= 0) {
_print_error(ret);
disconnect_from_stream();
@@ -234,6 +244,10 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
int ret = mbedtls_ssl_read(&ssl, p_buffer, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
ret = 0; // non blocking io
+ } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ // Clean close
+ disconnect_from_stream();
+ return ERR_FILE_EOF;
} else if (ret <= 0) {
_print_error(ret);
disconnect_from_stream();
@@ -256,9 +270,22 @@ void StreamPeerMbedTLS::poll() {
int ret = mbedtls_ssl_read(&ssl, NULL, 0);
- if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+ // Nothing to read/write (non blocking IO)
+ } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ // Clean close (disconnect)
+ disconnect_from_stream();
+ return;
+ } else if (ret < 0) {
_print_error(ret);
disconnect_from_stream();
+ return;
+ }
+
+ Ref<StreamPeerTCP> tcp = base;
+ if (tcp.is_valid() && tcp->get_status() != STATUS_CONNECTED) {
+ disconnect_from_stream();
+ return;
}
}
@@ -282,6 +309,12 @@ void StreamPeerMbedTLS::disconnect_from_stream() {
if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING)
return;
+ Ref<StreamPeerTCP> tcp = base;
+ if (tcp.is_valid() && tcp->get_status() == STATUS_CONNECTED) {
+ // We are still connected on the socket, try to send close notity.
+ mbedtls_ssl_close_notify(&ssl);
+ }
+
_cleanup();
}
@@ -317,15 +350,13 @@ void StreamPeerMbedTLS::initialize_ssl() {
mbedtls_debug_set_threshold(1);
#endif
- PoolByteArray cert_array = StreamPeerSSL::get_project_cert_array();
-
- if (cert_array.size() > 0)
- _load_certs(cert_array);
-
available = true;
}
void StreamPeerMbedTLS::finalize_ssl() {
+ available = false;
+ _create = NULL;
+ load_certs_func = NULL;
mbedtls_x509_crt_free(&cacert);
}
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index b3a2d26e4a..1d5c145027 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -134,6 +134,7 @@ def find_msbuild_unix(filename):
def find_msbuild_windows():
import mono_reg_utils as monoreg
+ mono_root = ''
bits = env['bits']
if bits == '32':
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 70fd1a35f1..01649a972e 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -99,6 +99,8 @@ def configure(env):
if not mono_root:
raise RuntimeError('Mono installation directory not found')
+ print('Found Mono root directory: ' + mono_root)
+
mono_version = mono_root_try_find_mono_version(mono_root)
configure_for_mono_version(env, mono_version)
@@ -164,6 +166,14 @@ def configure(env):
if os.getenv('MONO64_PREFIX'):
mono_root = os.getenv('MONO64_PREFIX')
+ if not mono_root and sys.platform == 'darwin':
+ # Try with some known directories under OSX
+ hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current', '/usr/local/var/homebrew/linked/mono']
+ for hint_dir in hint_dirs:
+ if os.path.isdir(hint_dir):
+ mono_root = hint_dir
+ break
+
# We can't use pkg-config to link mono statically,
# but we can still use it to find the mono root directory
if not mono_root and mono_static:
@@ -172,6 +182,8 @@ def configure(env):
raise RuntimeError('Building with mono_static=yes, but failed to find the mono prefix with pkg-config. Specify one manually')
if mono_root:
+ print('Found Mono root directory: ' + mono_root)
+
mono_version = mono_root_try_find_mono_version(mono_root)
configure_for_mono_version(env, mono_version)
@@ -216,6 +228,9 @@ def configure(env):
else:
assert not mono_static
+ # TODO: Add option to force using pkg-config
+ print('Mono root directory not found. Using pkg-config instead')
+
mono_version = pkgconfig_try_find_mono_version()
configure_for_mono_version(env, mono_version)
@@ -248,7 +263,7 @@ def configure(env):
def configure_for_mono_version(env, mono_version):
if mono_version is None:
raise RuntimeError('Mono JIT compiler version not found')
- print('Mono JIT compiler version: ' + str(mono_version))
+ print('Found Mono JIT compiler version: ' + str(mono_version))
if mono_version >= LooseVersion("5.12.0"):
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
@@ -282,7 +297,14 @@ def pkgconfig_try_find_mono_version():
def mono_root_try_find_mono_version(mono_root):
from compat import decode_utf8
- output = subprocess.check_output([os.path.join(mono_root, 'bin', 'mono'), '--version'])
+ mono_bin = os.path.join(mono_root, 'bin')
+ if os.path.isfile(os.path.join(mono_bin, 'mono')):
+ mono_binary = os.path.join(mono_bin, 'mono')
+ elif os.path.isfile(os.path.join(mono_bin, 'mono.exe')):
+ mono_binary = os.path.join(mono_bin, 'mono.exe')
+ else:
+ return None
+ output = subprocess.check_output([mono_binary, '--version'])
first_line = decode_utf8(output.splitlines()[0])
try:
return LooseVersion(first_line.split()[len('Mono JIT compiler version'.split())])
diff --git a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs b/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
index 303be3b732..fba4a8f65c 100644
--- a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
+++ b/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
@@ -2,13 +2,23 @@ using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
namespace GodotSharpTools.Editor
{
public class MonoDevelopInstance
{
- private Process process;
- private string solutionFile;
+ public enum EditorId
+ {
+ MonoDevelop = 0,
+ VisualStudioForMac = 1
+ }
+
+ readonly string solutionFile;
+ readonly EditorId editorId;
+
+ Process process;
public void Execute(string[] files)
{
@@ -16,6 +26,35 @@ namespace GodotSharpTools.Editor
List<string> args = new List<string>();
+ string command;
+
+ if (Utils.OS.IsOSX())
+ {
+ string bundleId = codeEditorBundleIds[editorId];
+
+ if (IsApplicationBundleInstalled(bundleId))
+ {
+ command = "open";
+
+ args.Add("-b");
+ args.Add(bundleId);
+
+ // The 'open' process must wait until the application finishes
+ if (newWindow)
+ args.Add("--wait-apps");
+
+ args.Add("--args");
+ }
+ else
+ {
+ command = codeEditorPaths[editorId];
+ }
+ }
+ else
+ {
+ command = codeEditorPaths[editorId];
+ }
+
args.Add("--ipc-tcp");
if (newWindow)
@@ -33,25 +72,73 @@ namespace GodotSharpTools.Editor
if (newWindow)
{
- ProcessStartInfo startInfo = new ProcessStartInfo(MonoDevelopFile, string.Join(" ", args));
- process = Process.Start(startInfo);
+ process = Process.Start(new ProcessStartInfo()
+ {
+ FileName = command,
+ Arguments = string.Join(" ", args),
+ UseShellExecute = false
+ });
}
else
{
- Process.Start(MonoDevelopFile, string.Join(" ", args));
+ Process.Start(new ProcessStartInfo()
+ {
+ FileName = command,
+ Arguments = string.Join(" ", args),
+ UseShellExecute = false
+ });
}
}
- public MonoDevelopInstance(string solutionFile)
+ public MonoDevelopInstance(string solutionFile, EditorId editorId)
{
+ if (editorId == EditorId.VisualStudioForMac && !Utils.OS.IsOSX())
+ throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
+
this.solutionFile = solutionFile;
+ this.editorId = editorId;
}
- private static string MonoDevelopFile
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern static bool IsApplicationBundleInstalled(string bundleId);
+
+ static readonly IReadOnlyDictionary<EditorId, string> codeEditorPaths;
+ static readonly IReadOnlyDictionary<EditorId, string> codeEditorBundleIds;
+
+ static MonoDevelopInstance()
{
- get
+ if (Utils.OS.IsOSX())
+ {
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // Rely on PATH
+ { EditorId.MonoDevelop, "monodevelop" },
+ { EditorId.VisualStudioForMac, "VisualStudio" }
+ };
+ codeEditorBundleIds = new Dictionary<EditorId, string>
+ {
+ // TODO EditorId.MonoDevelop
+ { EditorId.VisualStudioForMac, "com.microsoft.visual-studio" }
+ };
+ }
+ else if (Utils.OS.IsWindows())
+ {
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // XamarinStudio is no longer a thing, and the latest version is quite old
+ // MonoDevelop is available from source only on Windows. The recommendation
+ // is to use Visual Studio instead. Since there are no official builds, we
+ // will rely on custom MonoDevelop builds being added to PATH.
+ { EditorId.MonoDevelop, "MonoDevelop.exe" }
+ };
+ }
+ else if (Utils.OS.IsUnix())
{
- return "monodevelop";
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // Rely on PATH
+ { EditorId.MonoDevelop, "monodevelop" }
+ };
}
}
}
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
index 1c8714e31d..773e8196f7 100644
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
+++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
@@ -40,6 +40,7 @@
<Compile Include="Project\ProjectGenerator.cs" />
<Compile Include="Project\ProjectUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Utils\OS.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs b/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs
deleted file mode 100644
index 0cbafdc20d..0000000000
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs
+++ /dev/null
@@ -1,14 +0,0 @@
-<Properties StartupItem="GodotSharpTools.csproj">
- <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
- <MonoDevelop.Ide.Workbench ActiveDocument="Build/BuildSystem.cs">
- <Files>
- <File FileName="Build/ProjectExtensions.cs" Line="1" Column="1" />
- <File FileName="Build/ProjectGenerator.cs" Line="1" Column="1" />
- <File FileName="Build/BuildSystem.cs" Line="37" Column="14" />
- </Files>
- </MonoDevelop.Ide.Workbench>
- <MonoDevelop.Ide.DebuggingService.Breakpoints>
- <BreakpointStore />
- </MonoDevelop.Ide.DebuggingService.Breakpoints>
- <MonoDevelop.Ide.DebuggingService.PinnedWatches />
-</Properties> \ No newline at end of file
diff --git a/modules/mono/editor/GodotSharpTools/Utils/OS.cs b/modules/mono/editor/GodotSharpTools/Utils/OS.cs
new file mode 100644
index 0000000000..148e954e77
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/Utils/OS.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace GodotSharpTools.Utils
+{
+ public static class OS
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetPlatformName();
+
+ const string HaikuName = "Haiku";
+ const string OSXName = "OSX";
+ const string ServerName = "Server";
+ const string UWPName = "UWP";
+ const string WindowsName = "Windows";
+ const string X11Name = "X11";
+
+ public static bool IsHaiku()
+ {
+ return HaikuName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsOSX()
+ {
+ return OSXName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsServer()
+ {
+ return ServerName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsUWP()
+ {
+ return UWPName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsWindows()
+ {
+ return WindowsName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsX11()
+ {
+ return X11Name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ static bool? IsUnixCache = null;
+ static readonly string[] UnixPlatforms = new string[] { HaikuName, OSXName, ServerName, X11Name };
+
+ public static bool IsUnix()
+ {
+ if (IsUnixCache.HasValue)
+ return IsUnixCache.Value;
+
+ string osName = GetPlatformName();
+ IsUnixCache = UnixPlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase));
+ return IsUnixCache.Value;
+ }
+ }
+}
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index b01f8e66c3..d397814fa7 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -94,7 +94,12 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
#if defined(WINDOWS_ENABLED)
switch (build_tool) {
case GodotSharpBuilds::MSBUILD_VS: {
- static String msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path();
+ static String msbuild_tools_path;
+
+ if (msbuild_tools_path.empty() || !FileAccess::exists(msbuild_tools_path)) {
+ // Try to search it again if it wasn't found last time or if it was removed from its location
+ msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path();
+ }
if (msbuild_tools_path.length()) {
if (!msbuild_tools_path.ends_with("\\"))
@@ -128,15 +133,25 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() {
CRASH_NOW();
}
#elif defined(UNIX_ENABLED)
- static String msbuild_path = _find_build_engine_on_unix("msbuild");
- static String xbuild_path = _find_build_engine_on_unix("xbuild");
+ static String msbuild_path;
+ static String xbuild_path;
if (build_tool == GodotSharpBuilds::XBUILD) {
+ if (xbuild_path.empty() || !FileAccess::exists(xbuild_path)) {
+ // Try to search it again if it wasn't found last time or if it was removed from its location
+ xbuild_path = _find_build_engine_on_unix("msbuild");
+ }
+
if (xbuild_path.empty()) {
WARN_PRINT("Cannot find binary for '" PROP_NAME_XBUILD "'");
return NULL;
}
} else {
+ if (msbuild_path.empty() || !FileAccess::exists(msbuild_path)) {
+ // Try to search it again if it wasn't found last time or if it was removed from its location
+ msbuild_path = _find_build_engine_on_unix("msbuild");
+ }
+
if (msbuild_path.empty()) {
WARN_PRINT("Cannot find binary for '" PROP_NAME_MSBUILD_MONO "'");
return NULL;
@@ -192,7 +207,11 @@ MonoBoolean godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows() {
#endif
}
-void GodotSharpBuilds::_register_internal_calls() {
+void GodotSharpBuilds::register_internal_calls() {
+
+ static bool registered = false;
+ ERR_FAIL_COND(registered);
+ registered = true;
mono_add_internal_call("GodotSharpTools.Build.BuildSystem::godot_icall_BuildInstance_ExitCallback", (void *)godot_icall_BuildInstance_ExitCallback);
mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildPath", (void *)godot_icall_BuildInstance_get_MSBuildPath);
diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h
index 4afc284d45..c6dc6b6236 100644
--- a/modules/mono/editor/godotsharp_builds.h
+++ b/modules/mono/editor/godotsharp_builds.h
@@ -61,9 +61,6 @@ private:
static GodotSharpBuilds *singleton;
- friend class GDMono;
- static void _register_internal_calls();
-
public:
enum BuildTool {
MSBUILD_MONO,
@@ -75,6 +72,8 @@ public:
_FORCE_INLINE_ static GodotSharpBuilds *get_singleton() { return singleton; }
+ static void register_internal_calls();
+
static void show_build_error_dialog(const String &p_message);
void build_exit_callback(const MonoBuildInfo &p_build_info, int p_exit_code);
diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp
index faeb58e5a7..3ee38515bf 100644
--- a/modules/mono/editor/godotsharp_editor.cpp
+++ b/modules/mono/editor/godotsharp_editor.cpp
@@ -38,12 +38,17 @@
#include "../csharp_script.h"
#include "../godotsharp_dirs.h"
#include "../mono_gd/gd_mono.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "../utils/path_utils.h"
#include "bindings_generator.h"
#include "csharp_project.h"
#include "godotsharp_export.h"
#include "net_solution.h"
+#ifdef OSX_ENABLED
+#include "../utils/osx_utils.h"
+#endif
+
#ifdef WINDOWS_ENABLED
#include "../utils/mono_reg_utils.h"
#endif
@@ -169,6 +174,31 @@ void GodotSharpEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_menu_option_pressed", "id"), &GodotSharpEditor::_menu_option_pressed);
}
+MonoBoolean godot_icall_MonoDevelopInstance_IsApplicationBundleInstalled(MonoString *p_bundle_id) {
+#ifdef OSX_ENABLED
+ return (MonoBoolean)osx_is_app_bundle_installed(GDMonoMarshal::mono_string_to_godot(p_bundle_id));
+#else
+ (void)p_bundle_id; // UNUSED
+ ERR_FAIL_V(false);
+#endif
+}
+
+MonoString *godot_icall_Utils_OS_GetPlatformName() {
+ return GDMonoMarshal::mono_string_from_godot(OS::get_singleton()->get_name());
+}
+
+void GodotSharpEditor::register_internal_calls() {
+
+ static bool registered = false;
+ ERR_FAIL_COND(registered);
+ registered = true;
+
+ mono_add_internal_call("GodotSharpTools.Editor.MonoDevelopInstance::IsApplicationBundleInstalled", (void *)godot_icall_MonoDevelopInstance_IsApplicationBundleInstalled);
+ mono_add_internal_call("GodotSharpTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName);
+
+ GodotSharpBuilds::register_internal_calls();
+}
+
void GodotSharpEditor::show_error_dialog(const String &p_message, const String &p_title) {
error_dialog->set_title(p_title);
@@ -181,8 +211,36 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int
ExternalEditor editor = ExternalEditor(int(EditorSettings::get_singleton()->get("mono/editor/external_editor")));
switch (editor) {
- case EDITOR_CODE: {
+ case EDITOR_VSCODE: {
+ static String vscode_path;
+
+ if (vscode_path.empty() || !FileAccess::exists(vscode_path)) {
+ // Try to search it again if it wasn't found last time or if it was removed from its location
+ vscode_path = path_which("code");
+ }
+
List<String> args;
+
+#ifdef OSX_ENABLED
+ // The package path is '/Applications/Visual Studio Code.app'
+ static const String vscode_bundle_id = "com.microsoft.VSCode";
+ static bool osx_app_bundle_installed = osx_is_app_bundle_installed(vscode_bundle_id);
+
+ if (osx_app_bundle_installed) {
+ args.push_back("-b");
+ args.push_back(vscode_bundle_id);
+
+ // The reusing of existing windows made by the 'open' command might not choose a wubdiw that is
+ // editing our folder. It's better to ask for a new window and let VSCode do the window management.
+ args.push_back("-n");
+
+ // The open process must wait until the application finishes (which is instant in VSCode's case)
+ args.push_back("--wait-apps");
+
+ args.push_back("--args");
+ }
+#endif
+
args.push_back(ProjectSettings::get_singleton()->get_resource_path());
String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
@@ -194,18 +252,47 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int
args.push_back(script_path);
}
- static String program = path_which("code");
+#ifdef OSX_ENABLED
+ ERR_EXPLAIN("Cannot find code editor: VSCode");
+ ERR_FAIL_COND_V(!osx_app_bundle_installed && vscode_path.empty(), ERR_FILE_NOT_FOUND);
- Error err = OS::get_singleton()->execute(program.length() ? program : "code", args, false);
+ String command = osx_app_bundle_installed ? "/usr/bin/open" : vscode_path;
+#else
+ ERR_EXPLAIN("Cannot find code editor: VSCode");
+ ERR_FAIL_COND_V(vscode_path.empty(), ERR_FILE_NOT_FOUND);
+
+ String command = vscode_path;
+#endif
+
+ Error err = OS::get_singleton()->execute(command, args, false);
if (err != OK) {
- ERR_PRINT("GodotSharp: Could not execute external editor");
+ ERR_PRINT("Error when trying to execute code editor: VSCode");
return err;
}
} break;
+#ifdef OSX_ENABLED
+ case EDITOR_VISUALSTUDIO_MAC:
+ // [[fallthrough]];
+#endif
case EDITOR_MONODEVELOP: {
- if (!monodevel_instance)
- monodevel_instance = memnew(MonoDevelopInstance(GodotSharpDirs::get_project_sln_path()));
+#ifdef OSX_ENABLED
+ bool is_visualstudio = editor == EDITOR_VISUALSTUDIO_MAC;
+
+ MonoDevelopInstance **instance = is_visualstudio ?
+ &visualstudio_mac_instance :
+ &monodevelop_instance;
+
+ MonoDevelopInstance::EditorId editor_id = is_visualstudio ?
+ MonoDevelopInstance::VISUALSTUDIO_FOR_MAC :
+ MonoDevelopInstance::MONODEVELOP;
+#else
+ MonoDevelopInstance **instance = &monodevelop_instance;
+ MonoDevelopInstance::EditorId editor_id = MonoDevelopInstance::MONODEVELOP;
+#endif
+
+ if (!*instance)
+ *instance = memnew(MonoDevelopInstance(GodotSharpDirs::get_project_sln_path(), editor_id));
String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
@@ -213,7 +300,7 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int
script_path += ";" + itos(p_line + 1) + ";" + itos(p_col);
}
- monodevel_instance->execute(script_path);
+ (*instance)->execute(script_path);
} break;
default:
return ERR_UNAVAILABLE;
@@ -231,7 +318,10 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) {
singleton = this;
- monodevel_instance = NULL;
+ monodevelop_instance = NULL;
+#ifdef OSX_ENABLED
+ visualstudio_mac_instance = NULL;
+#endif
editor = p_editor;
@@ -314,7 +404,18 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) {
// External editor settings
EditorSettings *ed_settings = EditorSettings::get_singleton();
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"));
+
+ String settings_hint_str = "None";
+
+#ifdef WINDOWS_ENABLED
+ settings_hint_str += ",MonoDevelop,Visual Studio Code";
+#elif OSX_ENABLED
+ settings_hint_str += ",Visual Studio,MonoDevelop,Visual Studio Code";
+#elif UNIX_ENABLED
+ settings_hint_str += ",MonoDevelop,Visual Studio Code";
+#endif
+
+ ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/editor/external_editor", PROPERTY_HINT_ENUM, settings_hint_str));
// Export plugin
Ref<GodotSharpExport> godotsharp_export;
@@ -328,9 +429,9 @@ GodotSharpEditor::~GodotSharpEditor() {
memdelete(godotsharp_builds);
- if (monodevel_instance) {
- memdelete(monodevel_instance);
- monodevel_instance = NULL;
+ if (monodevelop_instance) {
+ memdelete(monodevelop_instance);
+ monodevelop_instance = NULL;
}
}
diff --git a/modules/mono/editor/godotsharp_editor.h b/modules/mono/editor/godotsharp_editor.h
index 66da814c8b..46b6bd5ebf 100644
--- a/modules/mono/editor/godotsharp_editor.h
+++ b/modules/mono/editor/godotsharp_editor.h
@@ -50,7 +50,10 @@ class GodotSharpEditor : public Node {
GodotSharpBuilds *godotsharp_builds;
- MonoDevelopInstance *monodevel_instance;
+ MonoDevelopInstance *monodevelop_instance;
+#ifdef OSX_ENABLED
+ MonoDevelopInstance *visualstudio_mac_instance;
+#endif
bool _create_project_solution();
@@ -74,12 +77,24 @@ public:
enum ExternalEditor {
EDITOR_NONE,
+#ifdef WINDOWS_ENABLED
+ //EDITOR_VISUALSTUDIO, // TODO
EDITOR_MONODEVELOP,
- EDITOR_CODE,
+ EDITOR_VSCODE
+#elif OSX_ENABLED
+ EDITOR_VISUALSTUDIO_MAC,
+ EDITOR_MONODEVELOP,
+ EDITOR_VSCODE
+#elif UNIX_ENABLED
+ EDITOR_MONODEVELOP,
+ EDITOR_VSCODE
+#endif
};
_FORCE_INLINE_ static GodotSharpEditor *get_singleton() { return singleton; }
+ static void register_internal_calls();
+
void show_error_dialog(const String &p_message, const String &p_title = "Error");
Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col);
diff --git a/modules/mono/editor/monodevelop_instance.cpp b/modules/mono/editor/monodevelop_instance.cpp
index 9f05711fd6..1d858d80bf 100644
--- a/modules/mono/editor/monodevelop_instance.cpp
+++ b/modules/mono/editor/monodevelop_instance.cpp
@@ -47,7 +47,7 @@ void MonoDevelopInstance::execute(const Vector<String> &p_files) {
execute_method->invoke(gc_handle->get_target(), args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL();
}
}
@@ -59,7 +59,7 @@ void MonoDevelopInstance::execute(const String &p_file) {
execute(files);
}
-MonoDevelopInstance::MonoDevelopInstance(const String &p_solution) {
+MonoDevelopInstance::MonoDevelopInstance(const String &p_solution, EditorId p_editor_id) {
_GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN)
@@ -67,15 +67,16 @@ MonoDevelopInstance::MonoDevelopInstance(const String &p_solution) {
MonoObject *obj = mono_object_new(TOOLS_DOMAIN, klass->get_mono_ptr());
- GDMonoMethod *ctor = klass->get_method(".ctor", 1);
+ GDMonoMethod *ctor = klass->get_method(".ctor", 2);
MonoException *exc = NULL;
Variant solution = p_solution;
- const Variant *args[1] = { &solution };
+ Variant editor_id = p_editor_id;
+ const Variant *args[2] = { &solution, &editor_id };
ctor->invoke(obj, args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL();
}
diff --git a/modules/mono/editor/monodevelop_instance.h b/modules/mono/editor/monodevelop_instance.h
index 73cf0f54cc..29de4a4735 100644
--- a/modules/mono/editor/monodevelop_instance.h
+++ b/modules/mono/editor/monodevelop_instance.h
@@ -42,10 +42,15 @@ class MonoDevelopInstance {
GDMonoMethod *execute_method;
public:
+ enum EditorId {
+ MONODEVELOP = 0,
+ VISUALSTUDIO_FOR_MAC = 1
+ };
+
void execute(const Vector<String> &p_files);
void execute(const String &p_file);
- MonoDevelopInstance(const String &p_solution);
+ MonoDevelopInstance(const String &p_solution, EditorId p_editor_id);
};
#endif // MONODEVELOP_INSTANCE_H
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index ec96a9e2fa..a5618cb28d 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -165,6 +165,38 @@ namespace Godot
);
}
+ internal Quat RotationQuat()
+ {
+ Basis orthonormalizedBasis = Orthonormalized();
+ real_t det = orthonormalizedBasis.Determinant();
+ if (det < 0)
+ {
+ // Ensure that the determinant is 1, such that result is a proper rotation matrix which can be represented by Euler angles.
+ orthonormalizedBasis = orthonormalizedBasis.Scaled(Vector3.NegOne);
+ }
+
+ return orthonormalizedBasis.Quat();
+ }
+
+ internal void SetQuantScale(Quat quat, Vector3 scale)
+ {
+ SetDiagonal(scale);
+ Rotate(quat);
+ }
+
+ private void Rotate(Quat quat)
+ {
+ this *= new Basis(quat);
+ }
+
+ private void SetDiagonal(Vector3 diagonal)
+ {
+ _x = new Vector3(diagonal.x, 0, 0);
+ _y = new Vector3(0, diagonal.y, 0);
+ _z = new Vector3(0, 0, diagonal.z);
+
+ }
+
public real_t Determinant()
{
return this[0, 0] * (this[1, 1] * this[2, 2] - this[2, 1] * this[1, 2]) -
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
index e432d5b52c..068007d7f0 100644
--- a/modules/mono/glue/Managed/Files/Transform.cs
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -20,6 +20,25 @@ namespace Godot
return new Transform(basisInv, basisInv.Xform(-origin));
}
+ public Transform InterpolateWith(Transform transform, real_t c)
+ {
+ /* not sure if very "efficient" but good enough? */
+
+ Vector3 sourceScale = basis.Scale;
+ Quat sourceRotation = basis.RotationQuat();
+ Vector3 sourceLocation = origin;
+
+ Vector3 destinationScale = transform.basis.Scale;
+ Quat destinationRotation = transform.basis.RotationQuat();
+ Vector3 destinationLocation = transform.origin;
+
+ var interpolated = new Transform();
+ interpolated.basis.SetQuantScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
+ interpolated.origin = sourceLocation.LinearInterpolate(destinationLocation, c);
+
+ return interpolated;
+ }
+
public Transform Inverse()
{
Basis basisTr = basis.Transposed();
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 03418a02ea..2fed6064b7 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -319,7 +319,7 @@ void GDMono::_register_internal_calls() {
#endif
#ifdef TOOLS_ENABLED
- GodotSharpBuilds::_register_internal_calls();
+ GodotSharpEditor::register_internal_calls();
#endif
}
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp
new file mode 100644
index 0000000000..f520706a0c
--- /dev/null
+++ b/modules/mono/utils/osx_utils.cpp
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* osx_utils.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 "osx_utils.h"
+
+#include "core/print_string.h"
+
+#ifdef OSX_ENABLED
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
+
+bool osx_is_app_bundle_installed(const String &p_bundle_id) {
+
+ CFURLRef app_url = NULL;
+ CFStringRef bundle_id = CFStringCreateWithCString(NULL, p_bundle_id.utf8(), kCFStringEncodingUTF8);
+ OSStatus result = LSFindApplicationForInfo(kLSUnknownCreator, bundle_id, NULL, NULL, &app_url);
+ CFRelease(bundle_id);
+
+ if (app_url)
+ CFRelease(app_url);
+
+ switch (result) {
+ case noErr:
+ return true;
+ case kLSApplicationNotFoundErr:
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+#endif
diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h
new file mode 100644
index 0000000000..68479b4f44
--- /dev/null
+++ b/modules/mono/utils/osx_utils.h
@@ -0,0 +1,41 @@
+/*************************************************************************/
+/* osx_utils.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 "core/ustring.h"
+
+#ifndef OSX_UTILS_H
+
+#ifdef OSX_ENABLED
+
+bool osx_is_app_bundle_installed(const String &p_bundle_id);
+
+#endif
+
+#endif // OSX_UTILS_H
diff --git a/modules/opensimplex/doc_classes/SimplexNoise.xml b/modules/opensimplex/doc_classes/SimplexNoise.xml
index a5a01d88a7..e5e0c15b3c 100644
--- a/modules/opensimplex/doc_classes/SimplexNoise.xml
+++ b/modules/opensimplex/doc_classes/SimplexNoise.xml
@@ -4,9 +4,7 @@
Noise generator based on Open Simplex.
</brief_description>
<description>
- This resource allows you to configure and sample a fractal noise space.
-
- Here is a brief usage example that configures a SimplexNoise and gets samples at various positions and dimensions:
+ This resource allows you to configure and sample a fractal noise space. Here is a brief usage example that configures a SimplexNoise and gets samples at various positions and dimensions:
[codeblock]
var noise = SimplexNoise.new()
@@ -14,13 +12,13 @@
noise.seed = randi()
noise.octaves = 4
noise.period = 20.0
- noise.persistance = 0.8
-
- #Sample
+ noise.persistence = 0.8
+
+ # Sample
print("Values:")
- print(noise.get_noise_2d(1.0,1.0))
- print(noise.get_noise_3d(0.5,3.0,15.0))
- print(noise.get_noise_3d(0.5,1.9,4.7,0.0))
+ print(noise.get_noise_2d(1.0, 1.0))
+ print(noise.get_noise_3d(0.5, 3.0, 15.0))
+ print(noise.get_noise_4d(0.5, 1.9, 4.7, 0.0))
[/codeblock]
</description>
<tutorials>
@@ -47,7 +45,7 @@
<argument index="1" name="y" type="float">
</argument>
<description>
- 2D noise value [-1,1] at position [code]x[/code],[code]y[/code].
+ Returns the 2D noise value [code][-1,1][/code] at the given position.
</description>
</method>
<method name="get_noise_2dv">
@@ -56,7 +54,7 @@
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
- 2D noise value [-1,1] at position [code]pos.x[/code],[code]pos.y[/code].
+ Returns the 2D noise value [code][-1,1][/code] at the given position.
</description>
</method>
<method name="get_noise_3d">
@@ -69,7 +67,7 @@
<argument index="2" name="z" type="float">
</argument>
<description>
- 3D noise value [-1,1] at position [code]x[/code],[code]y[/code],[code]z[/code].
+ Returns the 3D noise value [code][-1,1][/code] at the given position.
</description>
</method>
<method name="get_noise_3dv">
@@ -78,7 +76,7 @@
<argument index="0" name="pos" type="Vector3">
</argument>
<description>
- 3D noise value [-1,1] at position [code]pos.x[/code],[code]pos.y[/code],[code]pos.z[/code].
+ Returns the 3D noise value [code][-1,1][/code] at the given position.
</description>
</method>
<method name="get_noise_4d">
@@ -93,7 +91,7 @@
<argument index="3" name="w" type="float">
</argument>
<description>
- 4D noise value [-1,1] at position [code]x[/code],[code]y[/code],[code]z[/code],[code]w[/code].
+ Returns the 4D noise value [code][-1,1][/code] at the given position.
</description>
</method>
<method name="get_seamless_image">
@@ -102,8 +100,7 @@
<argument index="0" name="size" type="int">
</argument>
<description>
- Generate a tileable noise image, based on the current noise parameters.
- Generated seamless images are always square ([code]size[/code]x[code]size[/code]).
+ Generate a tileable noise image, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] x [code]size[/code]).
</description>
</method>
</methods>
@@ -112,15 +109,13 @@
Difference in period between [member octaves].
</member>
<member name="octaves" type="int" setter="set_octaves" getter="get_octaves">
- Number of Simplex Noise layers that are sampled to get the fractal noise.
+ Number of Simplex noise layers that are sampled to get the fractal noise.
</member>
<member name="period" type="float" setter="set_period" getter="get_period">
- Period of the base octave.
- A lower period results in a higher frequancy noise (more value changes across the same distance).
+ Period of the base octave. A lower period results in a higher-frequency noise (more value changes across the same distance).
</member>
- <member name="persistance" type="float" setter="set_persistance" getter="get_persistance">
- Contribuiton factor of the different octaves.
- A [code]persistance[/code] value of 1 means all the octaves have the same contribution, a value of 0.5 means each octave contributes half as much as the previous one.
+ <member name="persistence" type="float" setter="set_persistence" getter="get_persistence">
+ Contribution factor of the different octaves. A [code]persistence[/code] value of 1 means all the octaves have the same contribution, a value of 0.5 means each octave contributes half as much as the previous one.
</member>
<member name="seed" type="int" setter="set_seed" getter="get_seed">
Seed used to generate random values, different seeds will generate different noise maps.
diff --git a/modules/opensimplex/simplex_noise.cpp b/modules/opensimplex/simplex_noise.cpp
index 6d66c7110e..e489b7f6f0 100644
--- a/modules/opensimplex/simplex_noise.cpp
+++ b/modules/opensimplex/simplex_noise.cpp
@@ -35,7 +35,7 @@
SimplexNoise::SimplexNoise() {
seed = 0;
- persistance = 0.5;
+ persistence = 0.5;
octaves = 3;
period = 64;
lacunarity = 2.0;
@@ -81,9 +81,9 @@ void SimplexNoise::set_period(float p_period) {
emit_changed();
}
-void SimplexNoise::set_persistance(float p_persistance) {
- if (p_persistance == persistance) return;
- persistance = p_persistance;
+void SimplexNoise::set_persistence(float p_persistence) {
+ if (p_persistence == persistence) return;
+ persistence = p_persistence;
emit_changed();
}
@@ -164,8 +164,8 @@ void SimplexNoise::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_period", "period"), &SimplexNoise::set_period);
ClassDB::bind_method(D_METHOD("get_period"), &SimplexNoise::get_period);
- ClassDB::bind_method(D_METHOD("set_persistance", "persistance"), &SimplexNoise::set_persistance);
- ClassDB::bind_method(D_METHOD("get_persistance"), &SimplexNoise::get_persistance);
+ ClassDB::bind_method(D_METHOD("set_persistence", "persistence"), &SimplexNoise::set_persistence);
+ ClassDB::bind_method(D_METHOD("get_persistence"), &SimplexNoise::get_persistence);
ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &SimplexNoise::set_lacunarity);
ClassDB::bind_method(D_METHOD("get_lacunarity"), &SimplexNoise::get_lacunarity);
@@ -183,7 +183,7 @@ void SimplexNoise::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, "1,6,1"), "set_octaves", "get_octaves");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistance", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistance", "get_persistance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
}
@@ -200,7 +200,7 @@ float SimplexNoise::get_noise_2d(float x, float y) {
while (++i < octaves) {
x *= lacunarity;
y *= lacunarity;
- amp *= persistance;
+ amp *= persistence;
max += amp;
sum += _get_octave_noise_2d(i, x, y) * amp;
}
@@ -223,7 +223,7 @@ float SimplexNoise::get_noise_3d(float x, float y, float z) {
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
- amp *= persistance;
+ amp *= persistence;
max += amp;
sum += _get_octave_noise_3d(i, x, y, z) * amp;
}
@@ -248,7 +248,7 @@ float SimplexNoise::get_noise_4d(float x, float y, float z, float w) {
y *= lacunarity;
z *= lacunarity;
w *= lacunarity;
- amp *= persistance;
+ amp *= persistence;
max += amp;
sum += _get_octave_noise_4d(i, x, y, z, w) * amp;
}
diff --git a/modules/opensimplex/simplex_noise.h b/modules/opensimplex/simplex_noise.h
index 59390c6172..9a48dbf809 100644
--- a/modules/opensimplex/simplex_noise.h
+++ b/modules/opensimplex/simplex_noise.h
@@ -44,7 +44,7 @@ class SimplexNoise : public Resource {
osn_context contexts[6];
int seed;
- float persistance; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
+ float persistence; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
int octaves; // Number of noise layers
float period; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
float lacunarity; // Controls period change across octaves. 2 is usually a good value to address all detail levels.
@@ -64,8 +64,8 @@ public:
void set_period(float p_period);
float get_period() const { return period; }
- void set_persistance(float p_persistance);
- float get_persistance() const { return persistance; }
+ void set_persistence(float p_persistence);
+ float get_persistence() const { return persistence; }
void set_lacunarity(float p_lacunarity);
float get_lacunarity() const { return lacunarity; }
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index e7a4e0c31f..60bc54afe4 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -260,7 +260,12 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_SQRT: {
return PropertyInfo(Variant::REAL, "s");
} break;
- case MATH_ATAN2:
+ case MATH_ATAN2: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "y");
+ else
+ return PropertyInfo(Variant::REAL, "x");
+ } break;
case MATH_FMOD:
case MATH_FPOSMOD: {
if (p_idx == 0)