summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/collision_polygon_2d.cpp3
-rw-r--r--scene/2d/physics_body_2d.cpp2
-rw-r--r--scene/3d/area.cpp17
-rw-r--r--scene/3d/area.h4
-rw-r--r--scene/3d/camera.cpp83
-rw-r--r--scene/3d/camera.h12
-rw-r--r--scene/3d/collision_object.cpp51
-rw-r--r--scene/3d/collision_object.h9
-rw-r--r--scene/3d/collision_polygon.cpp206
-rw-r--r--scene/3d/collision_polygon.h50
-rw-r--r--scene/3d/physics_body.cpp563
-rw-r--r--scene/3d/physics_body.h93
-rw-r--r--scene/3d/physics_joint.cpp1012
-rw-r--r--scene/3d/physics_joint.h307
-rw-r--r--scene/3d/vehicle_body.cpp214
-rw-r--r--scene/3d/vehicle_body.h45
-rw-r--r--scene/gui/tab_container.cpp6
-rw-r--r--scene/gui/tabs.cpp3
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/gui/video_player.cpp14
-rw-r--r--scene/main/scene_main_loop.cpp11
-rw-r--r--scene/main/viewport.cpp224
-rw-r--r--scene/main/viewport.h10
-rw-r--r--scene/register_scene_types.cpp14
-rw-r--r--scene/resources/video_stream.h22
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h4
27 files changed, 2804 insertions, 179 deletions
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 5ab223a1b8..ef63286697 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -153,6 +153,7 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
ERR_FAIL_INDEX(p_mode,2);
build_mode=p_mode;
+ _update_parent();
}
CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const{
@@ -174,7 +175,7 @@ void CollisionPolygon2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon2D::set_build_mode);
ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon2D::get_build_mode);
- ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Automatic,Segments,Solids"),_SCS("set_build_mode"),_SCS("get_build_mode"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Segments"),_SCS("set_build_mode"),_SCS("get_build_mode"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index ecd147afde..47d78399b6 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -803,7 +803,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
//print_line("margin: "+rtos(margin));
do {
- //fill exclude list..
+ //motion recover
for(int i=0;i<get_shape_count();i++) {
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 964a086cf6..f5895453cc 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -255,6 +255,17 @@ bool Area::is_monitoring_enabled() const {
}
+void Area::set_ray_pickable(bool p_ray_pickable) {
+
+ ray_pickable=p_ray_pickable;
+ PhysicsServer::get_singleton()->area_set_ray_pickable(get_rid(),p_ray_pickable);
+}
+
+bool Area::is_ray_pickable() const {
+
+ return ray_pickable;
+}
+
void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_body_enter_scene","id"),&Area::_body_enter_scene);
@@ -278,6 +289,9 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
+ ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&Area::set_ray_pickable);
+ ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&Area::is_ray_pickable);
+
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled);
@@ -296,6 +310,7 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable"));
}
@@ -308,6 +323,8 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
density=0.1;
priority=0;
monitoring=false;
+ ray_pickable=false;
+ set_enable_monitoring(true);
}
diff --git a/scene/3d/area.h b/scene/3d/area.h
index 79e98f9dab..92b5d39f59 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -52,6 +52,7 @@ private:
real_t density;
int priority;
bool monitoring;
+ bool ray_pickable;
void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape);
@@ -108,6 +109,9 @@ public:
void set_priority(real_t p_priority);
real_t get_priority() const;
+ void set_ray_pickable(bool p_ray_pickable);
+ bool is_ray_pickable() const;
+
void set_enable_monitoring(bool p_enable);
bool is_monitoring_enabled() const;
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 56fbf358bc..4245bfa2c9 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -74,16 +74,18 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) {
mode=PROJECTION_ORTHOGONAL;
changed_all=true;
- } else if (p_name=="fov")
+ } else if (p_name=="fov" || p_name=="fovy" || p_name=="fovx")
fov=p_value;
- else if (p_name=="size")
+ else if (p_name=="size" || p_name=="sizex" || p_name=="sizey")
size=p_value;
else if (p_name=="near")
near=p_value;
else if (p_name=="far")
far=p_value;
+ else if (p_name=="keep_aspect")
+ set_keep_aspect_mode(KeepAspect(int(p_value)));
else if (p_name=="vaspect")
- set_use_vertical_aspect(p_value);
+ set_keep_aspect_mode(p_value?KEEP_WIDTH:KEEP_HEIGHT);
else if (p_name=="current") {
if (p_value.operator bool()) {
make_current();
@@ -107,16 +109,16 @@ bool Camera::_get(const StringName& p_name,Variant &r_ret) const {
if (p_name=="projection") {
r_ret= mode;
- } else if (p_name=="fov")
+ } else if (p_name=="fov" || p_name=="fovy" || p_name=="fovx")
r_ret= fov;
- else if (p_name=="size")
+ else if (p_name=="size" || p_name=="sizex" || p_name=="sizey")
r_ret= size;
else if (p_name=="near")
r_ret= near;
else if (p_name=="far")
r_ret= far;
- else if (p_name=="vaspect")
- r_ret= vaspect;
+ else if (p_name=="keep_aspect")
+ r_ret= int(keep_aspect);
else if (p_name=="current") {
if (is_inside_scene() && get_scene()->is_editor_hint()) {
@@ -142,19 +144,29 @@ void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
case PROJECTION_PERSPECTIVE: {
- p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,89,0.1") );
+ p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_NOEDITOR) );
+ if (keep_aspect==KEEP_WIDTH)
+ p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) );
+ else
+ p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) );
+
} break;
case PROJECTION_ORTHOGONAL: {
- p_list->push_back( PropertyInfo( Variant::REAL, "size" , PROPERTY_HINT_RANGE, "1,16384,0.01" ) );
+ p_list->push_back( PropertyInfo( Variant::REAL, "size" , PROPERTY_HINT_RANGE, "1,16384,0.01",PROPERTY_USAGE_NOEDITOR ) );
+ if (keep_aspect==KEEP_WIDTH)
+ p_list->push_back( PropertyInfo( Variant::REAL, "sizex" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
+ else
+ p_list->push_back( PropertyInfo( Variant::REAL, "sizey" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
+
} break;
}
p_list->push_back( PropertyInfo( Variant::REAL, "near" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
p_list->push_back( PropertyInfo( Variant::REAL, "far" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "vaspect") );
+ p_list->push_back( PropertyInfo( Variant::INT, "keep_aspect",PROPERTY_HINT_ENUM,"Keep Width,Keep Height") );
p_list->push_back( PropertyInfo( Variant::BOOL, "current" ) );
p_list->push_back( PropertyInfo( Variant::INT, "visible_layers",PROPERTY_HINT_ALL_FLAGS ) );
p_list->push_back( PropertyInfo( Variant::OBJECT, "environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment" ) );
@@ -441,7 +453,7 @@ Vector3 Camera::project_local_ray_normal(const Point2& p_pos) const {
ray=Vector3(0,0,-1);
} else {
CameraMatrix cm;
- cm.set_perspective(fov,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
float screen_w,screen_h;
cm.get_viewport_size(screen_w,screen_h);
ray=Vector3( ((p_pos.x/viewport_size.width)*2.0-1.0)*screen_w, ((1.0-(p_pos.y/viewport_size.height))*2.0-1.0)*screen_h,-near).normalized();
@@ -472,7 +484,7 @@ Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
Vector2 pos = p_pos / viewport_size;
float vsize,hsize;
- if (vaspect) {
+ if (keep_aspect==KEEP_WIDTH) {
vsize = size/viewport_size.get_aspect();
hsize = size;
} else {
@@ -503,9 +515,9 @@ Point2 Camera::unproject_position(const Vector3& p_pos) const {
if (mode==PROJECTION_ORTHOGONAL)
- cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
else
- cm.set_perspective(fov,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
Plane p(get_camera_transform().xform_inv(p_pos),1.0);
@@ -533,9 +545,9 @@ Vector3 Camera::project_position(const Point2& p_point) const {
CameraMatrix cm;
if (mode==PROJECTION_ORTHOGONAL)
- cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
else
- cm.set_perspective(fov,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
Size2 vp_size;
cm.get_viewport_size(vp_size.x,vp_size.y);
@@ -583,6 +595,20 @@ Ref<Environment> Camera::get_environment() const {
}
+void Camera::set_keep_aspect_mode(KeepAspect p_aspect) {
+
+ keep_aspect=p_aspect;
+ VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera,p_aspect==KEEP_WIDTH);
+
+ _change_notify();
+}
+
+Camera::KeepAspect Camera::get_keep_aspect_mode() const{
+
+ return keep_aspect;
+}
+
+
void Camera::_bind_methods() {
@@ -608,12 +634,16 @@ void Camera::_bind_methods() {
ObjectTypeDB::bind_method( _MD("look_at_from_pos","pos","target","up"),&Camera::look_at_from_pos );
ObjectTypeDB::bind_method(_MD("set_environment","env:Environment"),&Camera::set_environment);
ObjectTypeDB::bind_method(_MD("get_environment:Environment"),&Camera::get_environment);
- ObjectTypeDB::bind_method(_MD("set_use_vertical_aspect","enable"),&Camera::set_use_vertical_aspect);
- ObjectTypeDB::bind_method(_MD("is_using_vertical_aspect"),&Camera::is_using_vertical_aspect);
+ ObjectTypeDB::bind_method(_MD("set_keep_aspect_mode","mode"),&Camera::set_keep_aspect_mode);
+ ObjectTypeDB::bind_method(_MD("get_keep_aspect_mode"),&Camera::get_keep_aspect_mode);
//ObjectTypeDB::bind_method( _MD("_camera_make_current"),&Camera::_camera_make_current );
BIND_CONSTANT( PROJECTION_PERSPECTIVE );
BIND_CONSTANT( PROJECTION_ORTHOGONAL );
+
+ BIND_CONSTANT( KEEP_WIDTH );
+ BIND_CONSTANT( KEEP_HEIGHT );
+
}
float Camera::get_fov() const {
@@ -661,26 +691,15 @@ Vector<Plane> Camera::get_frustum() const {
Size2 viewport_size = viewport_ptr->get_visible_rect().size;
CameraMatrix cm;
if (mode==PROJECTION_PERSPECTIVE)
- cm.set_perspective(fov,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
else
- cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,vaspect);
+ cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
return cm.get_projection_planes(get_global_transform());
}
-void Camera::set_use_vertical_aspect(bool p_enable) {
-
- vaspect=p_enable;
- VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera,p_enable);
-}
-
-
-bool Camera::is_using_vertical_aspect() const{
-
- return vaspect;
-}
void Camera::look_at(const Vector3& p_target, const Vector3& p_up_normal) {
@@ -712,7 +731,7 @@ Camera::Camera() {
force_change=false;
mode=PROJECTION_PERSPECTIVE;
set_perspective(60.0,0.1,100.0);
- vaspect=false;
+ keep_aspect=KEEP_HEIGHT;
layers=0xFFFFFFFF;
//active=false;
}
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index a8599497ac..014c7cb520 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -46,6 +46,11 @@ public:
PROJECTION_ORTHOGONAL
};
+ enum KeepAspect {
+ KEEP_WIDTH,
+ KEEP_HEIGHT
+ };
+
private:
bool force_change;
@@ -56,7 +61,7 @@ private:
float fov;
float size;
float near,far;
- bool vaspect;
+ KeepAspect keep_aspect;
RID camera;
RID scenario_id;
@@ -126,8 +131,8 @@ public:
void set_environment(const Ref<Environment>& p_environment);
Ref<Environment> get_environment() const;
- void set_use_vertical_aspect(bool p_enable);
- bool is_using_vertical_aspect() const;
+ void set_keep_aspect_mode(KeepAspect p_aspect);
+ KeepAspect get_keep_aspect_mode() const;
void look_at(const Vector3& p_target, const Vector3& p_up_normal);
void look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal);
@@ -140,5 +145,6 @@ public:
VARIANT_ENUM_CAST( Camera::Projection );
+VARIANT_ENUM_CAST( Camera::KeepAspect );
#endif
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 7ad10d3222..06564f5c49 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "collision_object.h"
#include "servers/physics_server.h"
-
+#include "scene/scene_string_names.h"
void CollisionObject::_update_shapes_from_children() {
shapes.resize(0);
@@ -165,6 +165,34 @@ void CollisionObject::_get_property_list( List<PropertyInfo> *p_list) const {
}
}
+
+void CollisionObject::_input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape) {
+
+ if (get_script_instance()) {
+ get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_input_event,p_pos,p_normal,p_shape);
+ }
+ emit_signal(SceneStringNames::get_singleton()->input_event,p_input_event,p_pos,p_normal,p_shape);
+}
+
+void CollisionObject::_mouse_enter() {
+
+ if (get_script_instance()) {
+ get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_enter);
+ }
+ emit_signal(SceneStringNames::get_singleton()->mouse_enter);
+}
+
+
+void CollisionObject::_mouse_exit() {
+
+ if (get_script_instance()) {
+ get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit);
+ }
+ emit_signal(SceneStringNames::get_singleton()->mouse_exit);
+
+}
+
+
void CollisionObject::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_shape","shape:Shape","transform"),&CollisionObject::add_shape,DEFVAL(Transform()));
@@ -178,8 +206,16 @@ void CollisionObject::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_shape_transform","shape_idx"),&CollisionObject::get_shape_transform);
ObjectTypeDB::bind_method(_MD("remove_shape","shape_idx"),&CollisionObject::remove_shape);
ObjectTypeDB::bind_method(_MD("clear_shapes"),&CollisionObject::clear_shapes);
+ ObjectTypeDB::bind_method(_MD("set_capture_input_on_drag","enable"),&CollisionObject::set_capture_input_on_drag);
+ ObjectTypeDB::bind_method(_MD("get_capture_input_on_drag"),&CollisionObject::get_capture_input_on_drag);
ObjectTypeDB::bind_method(_MD("get_rid"),&CollisionObject::get_rid);
+ BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
+ ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
+ ADD_SIGNAL( MethodInfo("mouse_enter"));
+ ADD_SIGNAL( MethodInfo("mouse_exit"));
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"input/capture_on_drag"),_SCS("set_capture_input_on_drag"),_SCS("get_capture_input_on_drag"));
}
@@ -269,10 +305,23 @@ CollisionObject::CollisionObject(RID p_rid, bool p_area) {
}
+void CollisionObject::set_capture_input_on_drag(bool p_capture) {
+
+ capture_input_on_drag=p_capture;
+
+}
+
+bool CollisionObject::get_capture_input_on_drag() const {
+
+ return capture_input_on_drag;
+}
+
CollisionObject::CollisionObject() {
+ capture_input_on_drag=false;
+
//owner=
//set_transform_notify(true);
diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h
index 54dc6508ab..afd73aa9cc 100644
--- a/scene/3d/collision_object.h
+++ b/scene/3d/collision_object.h
@@ -50,6 +50,7 @@ class CollisionObject : public Spatial {
};
+ bool capture_input_on_drag;
Vector<ShapeData> shapes;
@@ -67,6 +68,11 @@ protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
static void _bind_methods();
+friend class Viewport;
+ virtual void _input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape);
+ virtual void _mouse_enter();
+ virtual void _mouse_exit();
+
public:
@@ -81,6 +87,9 @@ public:
void set_shape_as_trigger(int p_shape_idx, bool p_trigger);
bool is_shape_set_as_trigger(int p_shape_idx) const;
+ void set_capture_input_on_drag(bool p_capture);
+ bool get_capture_input_on_drag() const;
+
_FORCE_INLINE_ RID get_rid() const { return rid; }
CollisionObject();
diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp
new file mode 100644
index 0000000000..5a613f360a
--- /dev/null
+++ b/scene/3d/collision_polygon.cpp
@@ -0,0 +1,206 @@
+#include "collision_polygon.h"
+
+#include "collision_object.h"
+#include "scene/resources/concave_polygon_shape.h"
+#include "scene/resources/convex_polygon_shape.h"
+
+void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
+
+
+ CollisionObject *co = p_obj->cast_to<CollisionObject>();
+ ERR_FAIL_COND(!co);
+
+ if (polygon.size()==0)
+ return;
+
+ bool solids=build_mode==BUILD_SOLIDS;
+
+ Vector< Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
+ if (decomp.size()==0)
+ return;
+
+ if (true || solids) {
+
+ //here comes the sun, lalalala
+ //decompose concave into multiple convex polygons and add them
+ for(int i=0;i<decomp.size();i++) {
+ Ref<ConvexPolygonShape> convex = memnew( ConvexPolygonShape );
+ DVector<Vector3> cp;
+ int cs = decomp[i].size();
+ cp.resize(cs*2);
+ {
+ DVector<Vector3>::Write w = cp.write();
+ int idx=0;
+ for(int j=0;j<cs;j++) {
+
+ Vector2 d = decomp[i][j];
+ w[idx++]=Vector3(d.x,d.y,depth*0.5);
+ w[idx++]=Vector3(d.x,d.y,-depth*0.5);
+ }
+ }
+
+ convex->set_points(cp);
+ co->add_shape(convex,get_transform());
+
+ }
+
+ } else {
+#if 0
+ Ref<ConcavePolygonShape> concave = memnew( ConcavePolygonShape );
+
+ DVector<Vector2> segments;
+ segments.resize(polygon.size()*2);
+ DVector<Vector2>::Write w=segments.write();
+
+ for(int i=0;i<polygon.size();i++) {
+ w[(i<<1)+0]=polygon[i];
+ w[(i<<1)+1]=polygon[(i+1)%polygon.size()];
+ }
+
+ w=DVector<Vector2>::Write();
+ concave->set_segments(segments);
+
+ co->add_shape(concave,get_transform());
+#endif
+ }
+
+
+ //co->add_shape(shape,get_transform());
+
+}
+
+void CollisionPolygon::_update_parent() {
+
+ Node *parent = get_parent();
+ if (!parent)
+ return;
+ CollisionObject *co = parent->cast_to<CollisionObject>();
+ if (!co)
+ return;
+ co->_update_shapes_from_children();
+}
+
+void CollisionPolygon::_notification(int p_what) {
+
+
+ switch(p_what) {
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+
+ if (!is_inside_scene())
+ break;
+ _update_parent();
+
+ } break;
+#if 0
+ case NOTIFICATION_DRAW: {
+ for(int i=0;i<polygon.size();i++) {
+
+ Vector2 p = polygon[i];
+ Vector2 n = polygon[(i+1)%polygon.size()];
+ draw_line(p,n,Color(0,0.6,0.7,0.5),3);
+ }
+
+ Vector< Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
+#define DEBUG_DECOMPOSE
+#ifdef DEBUG_DECOMPOSE
+ Color c(0.4,0.9,0.1);
+ for(int i=0;i<decomp.size();i++) {
+
+ c.set_hsv( Math::fmod(c.get_h() + 0.738,1),c.get_s(),c.get_v(),0.5);
+ draw_colored_polygon(decomp[i],c);
+ }
+#endif
+
+ } break;
+#endif
+ }
+}
+
+void CollisionPolygon::set_polygon(const Vector<Point2>& p_polygon) {
+
+ polygon=p_polygon;
+
+ for(int i=0;i<polygon.size();i++) {
+
+ Vector3 p1(polygon[i].x,polygon[i].y,depth*0.5);
+
+ if (i==0)
+ aabb=AABB(p1,Vector3());
+ else
+ aabb.expand_to(p1);
+
+ Vector3 p2(polygon[i].x,polygon[i].y,-depth*0.5);
+ aabb.expand_to(p2);
+
+
+ }
+ if (aabb==AABB()) {
+
+ aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
+ } else {
+ aabb.pos-=aabb.size*0.3;
+ aabb.size+=aabb.size*0.6;
+ }
+ _update_parent();
+ update_gizmo();
+}
+
+Vector<Point2> CollisionPolygon::get_polygon() const {
+
+ return polygon;
+}
+
+void CollisionPolygon::set_build_mode(BuildMode p_mode) {
+
+ ERR_FAIL_INDEX(p_mode,2);
+ build_mode=p_mode;
+ _update_parent();
+}
+
+CollisionPolygon::BuildMode CollisionPolygon::get_build_mode() const{
+
+ return build_mode;
+}
+
+AABB CollisionPolygon::get_item_rect() const {
+
+ return aabb;
+}
+
+void CollisionPolygon::set_depth(float p_depth) {
+
+ depth=p_depth;
+ _update_parent();
+ update_gizmo();
+}
+
+float CollisionPolygon::get_depth() const {
+
+ return depth;
+}
+
+
+void CollisionPolygon::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon::_add_to_collision_object);
+ ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&CollisionPolygon::set_polygon);
+ ObjectTypeDB::bind_method(_MD("get_polygon"),&CollisionPolygon::get_polygon);
+
+ ObjectTypeDB::bind_method(_MD("set_depth","depth"),&CollisionPolygon::set_depth);
+ ObjectTypeDB::bind_method(_MD("get_depth"),&CollisionPolygon::get_depth);
+
+ ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon::set_build_mode);
+ ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon::get_build_mode);
+
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Triangles"),_SCS("set_build_mode"),_SCS("get_build_mode"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"depth"),_SCS("set_depth"),_SCS("get_depth"));
+}
+
+CollisionPolygon::CollisionPolygon() {
+
+ aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
+ build_mode=BUILD_SOLIDS;
+ depth=1.0;
+
+}
diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h
new file mode 100644
index 0000000000..efb3666778
--- /dev/null
+++ b/scene/3d/collision_polygon.h
@@ -0,0 +1,50 @@
+#ifndef COLLISION_POLYGON_H
+#define COLLISION_POLYGON_H
+
+#include "scene/3d/spatial.h"
+#include "scene/resources/shape.h"
+
+
+
+class CollisionPolygon : public Spatial {
+
+ OBJ_TYPE(CollisionPolygon,Spatial);
+public:
+
+ enum BuildMode {
+ BUILD_SOLIDS,
+ BUILD_TRIANGLES,
+ };
+
+protected:
+
+
+ float depth;
+ AABB aabb;
+ BuildMode build_mode;
+ Vector<Point2> polygon;
+
+ void _add_to_collision_object(Object *p_obj);
+ void _update_parent();
+
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ void set_build_mode(BuildMode p_mode);
+ BuildMode get_build_mode() const;
+
+ void set_depth(float p_depth);
+ float get_depth() const;
+
+ void set_polygon(const Vector<Point2>& p_polygon);
+ Vector<Point2> get_polygon() const;
+
+ virtual AABB get_item_rect() const;
+ CollisionPolygon();
+};
+
+VARIANT_ENUM_CAST( CollisionPolygon::BuildMode );
+#endif // COLLISION_POLYGON_H
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 721fd368e1..f5e3ad66ee 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -57,160 +57,111 @@ float PhysicsBody::get_inverse_mass() const {
return 0;
}
-PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : CollisionObject( PhysicsServer::get_singleton()->body_create(p_mode), false) {
-
+void PhysicsBody::set_layer_mask(uint32_t p_mask) {
+ layer_mask=p_mask;
+ PhysicsServer::get_singleton()->body_set_layer_mask(get_rid(),p_mask);
}
-void StaticBody::set_constant_linear_velocity(const Vector3& p_vel) {
-
- constant_linear_velocity=p_vel;
- PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_LINEAR_VELOCITY,constant_linear_velocity);
+uint32_t PhysicsBody::get_layer_mask() const {
+ return layer_mask;
}
-void StaticBody::set_constant_angular_velocity(const Vector3& p_vel) {
-
- constant_angular_velocity=p_vel;
- PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_ANGULAR_VELOCITY,constant_angular_velocity);
+void PhysicsBody::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask);
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
}
-Vector3 StaticBody::get_constant_linear_velocity() const {
-
- return constant_linear_velocity;
-}
-Vector3 StaticBody::get_constant_angular_velocity() const {
-
- return constant_angular_velocity;
-}
+PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : CollisionObject( PhysicsServer::get_singleton()->body_create(p_mode), false) {
-void StaticBody::_state_notify(Object *p_object) {
+ layer_mask=1;
- if (!pre_xform)
- return;
+}
- PhysicsDirectBodyState *p2d = (PhysicsDirectBodyState*)p_object;
- setting=true;
- Transform new_xform = p2d->get_transform();
- *pre_xform=new_xform;
- set_ignore_transform_notification(true);
- set_global_transform(new_xform);
- set_ignore_transform_notification(false);
+void StaticBody::set_friction(real_t p_friction){
- setting=false;
+ ERR_FAIL_COND(p_friction<0 || p_friction>1);
+ friction=p_friction;
+ PhysicsServer::get_singleton()->body_set_param(get_rid(),PhysicsServer::BODY_PARAM_FRICTION,friction);
}
+real_t StaticBody::get_friction() const{
-void StaticBody::_update_xform() {
-
- if (!pre_xform || !pending)
- return;
-
- setting=true;
-
-
- Transform new_xform = get_global_transform(); //obtain the new one
+ return friction;
+}
- //set_block_transform_notify(true);
- set_ignore_transform_notification(true);
- PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_TRANSFORM,*pre_xform); //then simulate motion!
- set_global_transform(*pre_xform); //but restore state to previous one in both visual and physics
- set_ignore_transform_notification(false);
+void StaticBody::set_bounce(real_t p_bounce){
- PhysicsServer::get_singleton()->body_static_simulate_motion(get_rid(),new_xform); //then simulate motion!
+ ERR_FAIL_COND(p_bounce<0 || p_bounce>1);
- setting=false;
- pending=false;
+ bounce=p_bounce;
+ PhysicsServer::get_singleton()->body_set_param(get_rid(),PhysicsServer::BODY_PARAM_BOUNCE,bounce);
}
+real_t StaticBody::get_bounce() const{
-void StaticBody::_notification(int p_what) {
-
- switch(p_what) {
-
- case NOTIFICATION_ENTER_SCENE: {
-
- if (pre_xform)
- *pre_xform = get_global_transform();
- pending=false;
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
+ return bounce;
+}
- if (simulating_motion && !pending && is_inside_scene() && !setting && !get_scene()->is_editor_hint()) {
+void StaticBody::set_constant_linear_velocity(const Vector3& p_vel) {
- call_deferred(SceneStringNames::get_singleton()->_update_xform);
- pending=true;
- }
+ constant_linear_velocity=p_vel;
+ PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_LINEAR_VELOCITY,constant_linear_velocity);
- } break;
- }
+}
+void StaticBody::set_constant_angular_velocity(const Vector3& p_vel) {
+ constant_angular_velocity=p_vel;
+ PhysicsServer::get_singleton()->body_set_state(get_rid(),PhysicsServer::BODY_STATE_ANGULAR_VELOCITY,constant_angular_velocity);
}
-void StaticBody::set_simulate_motion(bool p_enable) {
-
- if (p_enable==simulating_motion)
- return;
- simulating_motion=p_enable;
+Vector3 StaticBody::get_constant_linear_velocity() const {
- if (p_enable) {
- pre_xform = memnew( Transform );
- if (is_inside_scene())
- *pre_xform=get_transform();
-// query = PhysicsServer::get_singleton()->query_create(this,"_state_notify",Variant());
- // PhysicsServer::get_singleton()->query_body_direct_state(query,get_rid());
- PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),this,"_state_notify");
+ return constant_linear_velocity;
+}
+Vector3 StaticBody::get_constant_angular_velocity() const {
- } else {
- memdelete( pre_xform );
- pre_xform=NULL;
- PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),NULL,StringName());
- pending=false;
- }
+ return constant_angular_velocity;
}
-bool StaticBody::is_simulating_motion() const {
- return simulating_motion;
-}
void StaticBody::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("set_simulate_motion","enabled"),&StaticBody::set_simulate_motion);
- ObjectTypeDB::bind_method(_MD("is_simulating_motion"),&StaticBody::is_simulating_motion);
- ObjectTypeDB::bind_method(_MD("_update_xform"),&StaticBody::_update_xform);
- ObjectTypeDB::bind_method(_MD("_state_notify"),&StaticBody::_state_notify);
ObjectTypeDB::bind_method(_MD("set_constant_linear_velocity","vel"),&StaticBody::set_constant_linear_velocity);
ObjectTypeDB::bind_method(_MD("set_constant_angular_velocity","vel"),&StaticBody::set_constant_angular_velocity);
ObjectTypeDB::bind_method(_MD("get_constant_linear_velocity"),&StaticBody::get_constant_linear_velocity);
ObjectTypeDB::bind_method(_MD("get_constant_angular_velocity"),&StaticBody::get_constant_angular_velocity);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL,"simulate_motion"),_SCS("set_simulate_motion"),_SCS("is_simulating_motion"));
+ ObjectTypeDB::bind_method(_MD("set_friction","friction"),&StaticBody::set_friction);
+ ObjectTypeDB::bind_method(_MD("get_friction"),&StaticBody::get_friction);
+
+ ObjectTypeDB::bind_method(_MD("set_bounce","bounce"),&StaticBody::set_bounce);
+ ObjectTypeDB::bind_method(_MD("get_bounce"),&StaticBody::get_bounce);
+
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_friction"),_SCS("get_friction"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_bounce"),_SCS("get_bounce"));
+
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3,"constant_linear_velocity"),_SCS("set_constant_linear_velocity"),_SCS("get_constant_linear_velocity"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3,"constant_angular_velocity"),_SCS("set_constant_angular_velocity"),_SCS("get_constant_angular_velocity"));
}
StaticBody::StaticBody() : PhysicsBody(PhysicsServer::BODY_MODE_STATIC) {
- simulating_motion=false;
- pre_xform=NULL;
- setting=false;
- pending=false;
- //constant_angular_velocity=0;
-
+ bounce=0;
+ friction=1;
}
StaticBody::~StaticBody() {
- if (pre_xform)
- memdelete(pre_xform);
- //if (query.is_valid())
- // PhysicsServer::get_singleton()->free(query);
+
}
@@ -768,4 +719,418 @@ RigidBody::~RigidBody() {
}
+//////////////////////////////////////////////////////
+//////////////////////////
+
+
+Variant KinematicBody::_get_collider() const {
+
+ ObjectID oid=get_collider();
+ if (oid==0)
+ return Variant();
+ Object *obj = ObjectDB::get_instance(oid);
+ if (!obj)
+ return Variant();
+
+ Reference *ref = obj->cast_to<Reference>();
+ if (ref) {
+ return Ref<Reference>(ref);
+ }
+
+ return obj;
+}
+
+
+bool KinematicBody::_ignores_mode(PhysicsServer::BodyMode p_mode) const {
+
+ switch(p_mode) {
+ case PhysicsServer::BODY_MODE_STATIC: return !collide_static;
+ case PhysicsServer::BODY_MODE_KINEMATIC: return !collide_kinematic;
+ case PhysicsServer::BODY_MODE_RIGID: return !collide_rigid;
+ case PhysicsServer::BODY_MODE_CHARACTER: return !collide_character;
+ }
+
+ return true;
+}
+
+Vector3 KinematicBody::move(const Vector3& p_motion) {
+
+ //give me back regular physics engine logic
+ //this is madness
+ //and most people using this function will think
+ //what it does is simpler than using physics
+ //this took about a week to get right..
+ //but is it right? who knows at this point..
+
+
+ colliding=false;
+ ERR_FAIL_COND_V(!is_inside_scene(),Vector3());
+ PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
+ ERR_FAIL_COND_V(!dss,Vector3());
+ const int max_shapes=32;
+ Vector3 sr[max_shapes*2];
+ int res_shapes;
+
+ Set<RID> exclude;
+ exclude.insert(get_rid());
+
+
+ //recover first
+ int recover_attempts=4;
+
+ bool collided=false;
+ uint32_t mask=0;
+ if (collide_static)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_STATIC_BODY;
+ if (collide_kinematic)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
+ if (collide_rigid)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_RIGID_BODY;
+ if (collide_character)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
+
+// print_line("motion: "+p_motion+" margin: "+rtos(margin));
+
+ //print_line("margin: "+rtos(margin));
+
+ float m = margin;
+ //m=0.001;
+
+ do {
+
+ //motion recover
+ for(int i=0;i<get_shape_count();i++) {
+
+
+ if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),m,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask)) {
+ collided=true;
+ }
+
+ }
+
+
+
+ if (!collided)
+ break;
+
+ //print_line("have to recover");
+ Vector3 recover_motion;
+ bool all_outside=true;
+ for(int j=0;j<8;j++) {
+ for(int i=0;i<res_shapes;i++) {
+
+ Vector3 a = sr[i*2+0];
+ Vector3 b = sr[i*2+1];
+ //print_line(String()+a+" -> "+b);
+#if 0
+ float d = a.distance_to(b);
+
+ //if (d<margin)
+ /// continue;
+ ///
+ ///
+ recover_motion+=(b-a)*0.2;
+#else
+ float dist = a.distance_to(b);
+ if (dist>CMP_EPSILON) {
+ Vector3 norm = (b-a).normalized();
+ if (dist>margin*0.5)
+ all_outside=false;
+ float adv = norm.dot(recover_motion);
+ //print_line(itos(i)+" dist: "+rtos(dist)+" adv: "+rtos(adv));
+ recover_motion+=norm*MAX(dist-adv,0)*0.4;
+ }
+#endif
+
+ }
+ }
+
+
+ if (recover_motion==Vector3()) {
+ collided=false;
+ break;
+ }
+
+ //print_line("**** RECOVER: "+recover_motion);
+
+ Transform gt = get_global_transform();
+ gt.origin+=recover_motion;
+ set_global_transform(gt);
+
+ recover_attempts--;
+
+ if (all_outside)
+ break;
+
+ } while (recover_attempts);
+
+
+ //move second
+ float safe = 1.0;
+ float unsafe = 1.0;
+ int best_shape=-1;
+
+ PhysicsDirectSpaceState::ShapeRestInfo rest;
+
+ //print_line("pos: "+get_global_transform().origin);
+ //print_line("motion: "+p_motion);
+
+
+ for(int i=0;i<get_shape_count();i++) {
+
+
+
+ float lsafe,lunsafe;
+ PhysicsDirectSpaceState::ShapeRestInfo lrest;
+ bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion,0, lsafe,lunsafe,exclude,get_layer_mask(),mask,&lrest);
+ //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
+ if (!valid) {
+ safe=0;
+ unsafe=0;
+ best_shape=i; //sadly it's the best
+ //print_line("initial stuck");
+
+ break;
+ }
+ if (lsafe==1.0) {
+ //print_line("initial free");
+ continue;
+ }
+ if (lsafe < safe) {
+
+ //print_line("initial at "+rtos(lsafe));
+ safe=lsafe;
+ safe=MAX(0,lsafe-0.01);
+ unsafe=lunsafe;
+ best_shape=i;
+ rest=lrest;
+ }
+ }
+
+
+ //print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
+
+ if (safe>=1) {
+ //not collided
+ colliding=false;
+ } else {
+
+ colliding=true;
+
+ if (true || (safe==0 && unsafe==0)) { //use it always because it's more precise than GJK
+ //no advance, use rest info from collision
+ Transform ugt = get_global_transform();
+ ugt.origin+=p_motion*unsafe;
+
+ PhysicsDirectSpaceState::ShapeRestInfo rest_info;
+ bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), m,&rest,exclude,get_layer_mask(),mask);
+ if (!c2) {
+ //should not happen, but floating point precision is so weird..
+ colliding=false;
+ }
+
+ // print_line("Rest Travel: "+rest.normal);
+
+ }
+
+ if (colliding) {
+
+ collision=rest.point;
+ normal=rest.normal;
+ collider=rest.collider_id;
+ collider_vel=rest.linear_velocity;
+ }
+ }
+
+ Vector3 motion=p_motion*safe;
+ //if (colliding)
+ // motion+=normal*0.001;
+ Transform gt = get_global_transform();
+ gt.origin+=motion;
+ set_global_transform(gt);
+
+ return p_motion-motion;
+
+}
+
+Vector3 KinematicBody::move_to(const Vector3& p_position) {
+
+ return move(p_position-get_global_transform().origin);
+}
+
+bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
+
+ ERR_FAIL_COND_V(!is_inside_scene(),false);
+ PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
+ ERR_FAIL_COND_V(!dss,false);
+
+ uint32_t mask=0;
+ if (collide_static)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_STATIC_BODY;
+ if (collide_kinematic)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
+ if (collide_rigid)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_RIGID_BODY;
+ if (collide_character)
+ mask|=PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
+
+ Vector3 motion = p_position-get_global_transform().origin;
+ Transform xform=get_global_transform();
+
+ if (true || p_discrete) {
+
+ xform.origin+=motion;
+ motion=Vector3();
+ }
+
+ Set<RID> exclude;
+ exclude.insert(get_rid());
+
+ //fill exclude list..
+ for(int i=0;i<get_shape_count();i++) {
+
+
+ bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,0,exclude,get_layer_mask(),mask);
+ if (col)
+ return false;
+ }
+
+ return true;
+}
+
+bool KinematicBody::is_colliding() const {
+
+ ERR_FAIL_COND_V(!is_inside_scene(),false);
+
+ return colliding;
+}
+Vector3 KinematicBody::get_collision_pos() const {
+
+ ERR_FAIL_COND_V(!colliding,Vector3());
+ return collision;
+
+}
+Vector3 KinematicBody::get_collision_normal() const {
+
+ ERR_FAIL_COND_V(!colliding,Vector3());
+ return normal;
+
+}
+
+Vector3 KinematicBody::get_collider_velocity() const {
+
+ return collider_vel;
+}
+
+ObjectID KinematicBody::get_collider() const {
+
+ ERR_FAIL_COND_V(!colliding,0);
+ return collider;
+}
+
+void KinematicBody::set_collide_with_static_bodies(bool p_enable) {
+
+ collide_static=p_enable;
+}
+bool KinematicBody::can_collide_with_static_bodies() const {
+
+ return collide_static;
+}
+
+void KinematicBody::set_collide_with_rigid_bodies(bool p_enable) {
+
+ collide_rigid=p_enable;
+
+}
+bool KinematicBody::can_collide_with_rigid_bodies() const {
+
+
+ return collide_rigid;
+}
+
+void KinematicBody::set_collide_with_kinematic_bodies(bool p_enable) {
+
+ collide_kinematic=p_enable;
+
+}
+bool KinematicBody::can_collide_with_kinematic_bodies() const {
+
+ return collide_kinematic;
+}
+
+void KinematicBody::set_collide_with_character_bodies(bool p_enable) {
+
+ collide_character=p_enable;
+}
+bool KinematicBody::can_collide_with_character_bodies() const {
+
+ return collide_character;
+}
+
+void KinematicBody::set_collision_margin(float p_margin) {
+
+ margin=p_margin;
+}
+
+float KinematicBody::get_collision_margin() const{
+
+ return margin;
+}
+
+void KinematicBody::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody::move);
+ ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody::move_to);
+
+ ObjectTypeDB::bind_method(_MD("can_move_to","position"),&KinematicBody::can_move_to);
+
+ ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody::is_colliding);
+
+ ObjectTypeDB::bind_method(_MD("get_collision_pos"),&KinematicBody::get_collision_pos);
+ ObjectTypeDB::bind_method(_MD("get_collision_normal"),&KinematicBody::get_collision_normal);
+ ObjectTypeDB::bind_method(_MD("get_collider_velocity"),&KinematicBody::get_collider_velocity);
+ ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody::_get_collider);
+
+
+ ObjectTypeDB::bind_method(_MD("set_collide_with_static_bodies","enable"),&KinematicBody::set_collide_with_static_bodies);
+ ObjectTypeDB::bind_method(_MD("can_collide_with_static_bodies"),&KinematicBody::can_collide_with_static_bodies);
+
+ ObjectTypeDB::bind_method(_MD("set_collide_with_kinematic_bodies","enable"),&KinematicBody::set_collide_with_kinematic_bodies);
+ ObjectTypeDB::bind_method(_MD("can_collide_with_kinematic_bodies"),&KinematicBody::can_collide_with_kinematic_bodies);
+
+ ObjectTypeDB::bind_method(_MD("set_collide_with_rigid_bodies","enable"),&KinematicBody::set_collide_with_rigid_bodies);
+ ObjectTypeDB::bind_method(_MD("can_collide_with_rigid_bodies"),&KinematicBody::can_collide_with_rigid_bodies);
+
+ ObjectTypeDB::bind_method(_MD("set_collide_with_character_bodies","enable"),&KinematicBody::set_collide_with_character_bodies);
+ ObjectTypeDB::bind_method(_MD("can_collide_with_character_bodies"),&KinematicBody::can_collide_with_character_bodies);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_margin","pixels"),&KinematicBody::set_collision_margin);
+ ObjectTypeDB::bind_method(_MD("get_collision_margin","pixels"),&KinematicBody::get_collision_margin);
+
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/static"),_SCS("set_collide_with_static_bodies"),_SCS("can_collide_with_static_bodies"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/kinematic"),_SCS("set_collide_with_kinematic_bodies"),_SCS("can_collide_with_kinematic_bodies"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/rigid"),_SCS("set_collide_with_rigid_bodies"),_SCS("can_collide_with_rigid_bodies"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/character"),_SCS("set_collide_with_character_bodies"),_SCS("can_collide_with_character_bodies"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/margin",PROPERTY_HINT_RANGE,"0.001,256,0.001"),_SCS("set_collision_margin"),_SCS("get_collision_margin"));
+
+
+}
+
+KinematicBody::KinematicBody() : PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC){
+
+ collide_static=true;
+ collide_rigid=true;
+ collide_kinematic=true;
+ collide_character=true;
+
+ colliding=false;
+ collider=0;
+ margin=0.001;
+}
+KinematicBody::~KinematicBody() {
+
+
+}
+
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 616288e1f6..0b7a389449 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -38,8 +38,10 @@ class PhysicsBody : public CollisionObject {
OBJ_TYPE(PhysicsBody,CollisionObject);
+ uint32_t layer_mask;
protected:
+ static void _bind_methods();
void _notification(int p_what);
PhysicsBody(PhysicsServer::BodyMode p_mode);
public:
@@ -48,6 +50,10 @@ public:
virtual Vector3 get_angular_velocity() const;
virtual float get_inverse_mass() const;
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
+
PhysicsBody();
};
@@ -56,25 +62,26 @@ class StaticBody : public PhysicsBody {
OBJ_TYPE(StaticBody,PhysicsBody);
- Transform *pre_xform;
- //RID query;
- bool setting;
- bool pending;
- bool simulating_motion;
Vector3 constant_linear_velocity;
Vector3 constant_angular_velocity;
- void _update_xform();
- void _state_notify(Object *p_object);
+
+ real_t bounce;
+ real_t friction;
+
protected:
- void _notification(int p_what);
static void _bind_methods();
public:
- void set_simulate_motion(bool p_enable);
- bool is_simulating_motion() const;
+
+ void set_friction(real_t p_friction);
+ real_t get_friction() const;
+
+ void set_bounce(real_t p_bounce);
+ real_t get_bounce() const;
+
void set_constant_linear_velocity(const Vector3& p_vel);
void set_constant_angular_velocity(const Vector3& p_vel);
@@ -237,4 +244,70 @@ public:
VARIANT_ENUM_CAST(RigidBody::Mode);
VARIANT_ENUM_CAST(RigidBody::AxisLock);
+
+
+
+
+
+class KinematicBody : public PhysicsBody {
+
+ OBJ_TYPE(KinematicBody,PhysicsBody);
+
+ float margin;
+ bool collide_static;
+ bool collide_rigid;
+ bool collide_kinematic;
+ bool collide_character;
+
+ bool colliding;
+ Vector3 collision;
+ Vector3 normal;
+ Vector3 collider_vel;
+ ObjectID collider;
+
+
+ Variant _get_collider() const;
+
+ _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
+protected:
+
+ static void _bind_methods();
+public:
+
+ enum {
+ SLIDE_FLAG_FLOOR,
+ SLIDE_FLAG_WALL,
+ SLIDE_FLAG_ROOF
+ };
+
+ Vector3 move(const Vector3& p_motion);
+ Vector3 move_to(const Vector3& p_position);
+
+ bool can_move_to(const Vector3& p_position,bool p_discrete=false);
+ bool is_colliding() const;
+ Vector3 get_collision_pos() const;
+ Vector3 get_collision_normal() const;
+ Vector3 get_collider_velocity() const;
+ ObjectID get_collider() const;
+
+ void set_collide_with_static_bodies(bool p_enable);
+ bool can_collide_with_static_bodies() const;
+
+ void set_collide_with_rigid_bodies(bool p_enable);
+ bool can_collide_with_rigid_bodies() const;
+
+ void set_collide_with_kinematic_bodies(bool p_enable);
+ bool can_collide_with_kinematic_bodies() const;
+
+ void set_collide_with_character_bodies(bool p_enable);
+ bool can_collide_with_character_bodies() const;
+
+ void set_collision_margin(float p_margin);
+ float get_collision_margin() const;
+
+ KinematicBody();
+ ~KinematicBody();
+
+};
+
#endif // PHYSICS_BODY__H
diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp
index 961198c8d4..341b02314d 100644
--- a/scene/3d/physics_joint.cpp
+++ b/scene/3d/physics_joint.cpp
@@ -27,7 +27,1017 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "physics_joint.h"
-
+
+
+
+void Joint::_update_joint(bool p_only_free) {
+
+
+ if (joint.is_valid()) {
+ if (ba.is_valid() && bb.is_valid())
+ PhysicsServer::get_singleton()->body_remove_collision_exception(ba,bb);
+ PhysicsServer::get_singleton()->free(joint);
+ joint=RID();
+ ba=RID();
+ bb=RID();
+ }
+
+ if (p_only_free || !is_inside_scene())
+ return;
+
+ Node *node_a = has_node( get_node_a() ) ? get_node( get_node_a() ) : (Node*)NULL;
+ Node *node_b = has_node( get_node_b() ) ? get_node( get_node_b() ) : (Node*)NULL;
+
+ if (!node_a && !node_b)
+ return;
+
+ PhysicsBody *body_a=node_a ? node_a->cast_to<PhysicsBody>() : (PhysicsBody*)NULL;
+ PhysicsBody *body_b=node_b ? node_b->cast_to<PhysicsBody>() : (PhysicsBody*)NULL;
+
+ if (!body_a && !body_b)
+ return;
+
+ if (!body_a) {
+ SWAP(body_a,body_b);
+ } else if (body_b) {
+ //add a collision exception between both
+ PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ }
+
+ joint = _configure_joint(body_a,body_b);
+
+ if (body_b && joint.is_valid()) {
+
+ ba=body_a->get_rid();
+ bb=body_b->get_rid();
+ PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+
+ }
+
+}
+
+
+void Joint::set_node_a(const NodePath& p_node_a) {
+
+
+ if (a==p_node_a)
+ return;
+
+ a=p_node_a;
+ _update_joint();
+}
+
+NodePath Joint::get_node_a() const{
+
+ return a;
+}
+
+void Joint::set_node_b(const NodePath& p_node_b){
+
+ if (b==p_node_b)
+ return;
+ b=p_node_b;
+ _update_joint();
+
+}
+NodePath Joint::get_node_b() const{
+
+
+ return b;
+}
+
+
+void Joint::_notification(int p_what) {
+
+ switch(p_what) {
+
+ case NOTIFICATION_READY: {
+ _update_joint();
+ } break;
+ case NOTIFICATION_EXIT_SCENE: {
+ if (joint.is_valid()) {
+ _update_joint(true);
+
+
+ PhysicsServer::get_singleton()->free(joint);
+ joint=RID();
+ }
+ } break;
+
+ }
+
+}
+
+
+void Joint::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method( _MD("set_node_a","node"), &Joint::set_node_a );
+ ObjectTypeDB::bind_method( _MD("get_node_a"), &Joint::get_node_a );
+
+ ObjectTypeDB::bind_method( _MD("set_node_b","node"), &Joint::set_node_b );
+ ObjectTypeDB::bind_method( _MD("get_node_b"), &Joint::get_node_b );
+
+
+ ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
+ ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
+
+}
+
+
+
+Joint::Joint() {
+
+
+}
+
+
+///////////////////////////////////
+
+void PinJoint::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_param","param","value"),&PinJoint::set_param);
+ ObjectTypeDB::bind_method(_MD("get_param","param"),&PinJoint::get_param);
+
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/bias",PROPERTY_HINT_RANGE,"0.01,0.99,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_BIAS );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/damping",PROPERTY_HINT_RANGE,"0.01,8.0,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_DAMPING );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/impulse_clamp",PROPERTY_HINT_RANGE,"0.0,64.0,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_IMPULSE_CLAMP );
+
+ BIND_CONSTANT( PARAM_BIAS );
+ BIND_CONSTANT( PARAM_DAMPING );
+ BIND_CONSTANT( PARAM_IMPULSE_CLAMP );
+}
+
+void PinJoint::set_param(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,3);
+ params[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->pin_joint_set_param(get_joint(),PhysicsServer::PinJointParam(p_param),p_value);
+}
+float PinJoint::get_param(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,3,0);
+ return params[p_param];
+}
+
+
+RID PinJoint::_configure_joint(PhysicsBody *body_a,PhysicsBody *body_b) {
+
+
+ Vector3 pinpos = get_global_transform().origin;
+ Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos);
+ Vector3 local_b;
+
+ if (body_b)
+ local_b = body_b->get_global_transform().affine_inverse().xform(pinpos);
+ else
+ local_b=pinpos;
+
+ RID j = PhysicsServer::get_singleton()->joint_create_pin(body_a->get_rid(),local_a,body_b?body_b->get_rid():RID(),local_b);
+ for(int i=0;i<3;i++) {
+ PhysicsServer::get_singleton()->pin_joint_set_param(j,PhysicsServer::PinJointParam(i),params[i]);
+ }
+ return j;
+}
+
+
+PinJoint::PinJoint() {
+
+ params[PARAM_BIAS]=0.3;
+ params[PARAM_DAMPING]=1;
+ params[PARAM_IMPULSE_CLAMP]=0;
+
+}
+
+
+
+
+/////////////////////////////////////////////////
+
+
+
+///////////////////////////////////
+
+
+void HingeJoint::_set_upper_limit(float p_limit) {
+
+ set_param(PARAM_LIMIT_UPPER,Math::deg2rad(p_limit));
+}
+
+float HingeJoint::_get_upper_limit() const {
+
+ return Math::rad2deg(get_param(PARAM_LIMIT_UPPER));
+}
+
+void HingeJoint::_set_lower_limit(float p_limit) {
+
+ set_param(PARAM_LIMIT_LOWER,Math::deg2rad(p_limit));
+
+}
+
+float HingeJoint::_get_lower_limit() const {
+
+ return Math::rad2deg(get_param(PARAM_LIMIT_LOWER));
+
+}
+
+
+void HingeJoint::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_param","param","value"),&HingeJoint::set_param);
+ ObjectTypeDB::bind_method(_MD("get_param","param"),&HingeJoint::get_param);
+
+ ObjectTypeDB::bind_method(_MD("set_flag","flag","enabled"),&HingeJoint::set_flag);
+ ObjectTypeDB::bind_method(_MD("get_flag","flag"),&HingeJoint::get_flag);
+
+ ObjectTypeDB::bind_method(_MD("_set_upper_limit","upper_limit"),&HingeJoint::_set_upper_limit);
+ ObjectTypeDB::bind_method(_MD("_get_upper_limit"),&HingeJoint::_get_upper_limit);
+
+ ObjectTypeDB::bind_method(_MD("_set_lower_limit","lower_limit"),&HingeJoint::_set_lower_limit);
+ ObjectTypeDB::bind_method(_MD("_get_lower_limit"),&HingeJoint::_get_lower_limit);
+
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/bias",PROPERTY_HINT_RANGE,"0.01,0.99,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_BIAS );
+
+ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"angular_limit/enable"),_SCS("set_flag"),_SCS("get_flag"), FLAG_USE_LIMIT );
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_limit/upper",PROPERTY_HINT_RANGE,"-180,180,0.1"),_SCS("_set_upper_limit"),_SCS("_get_upper_limit") );
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_limit/lower",PROPERTY_HINT_RANGE,"-180,180,0.1"),_SCS("_set_lower_limit"),_SCS("_get_lower_limit") );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/bias",PROPERTY_HINT_RANGE,"0.01,0.99,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_LIMIT_BIAS );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_LIMIT_SOFTNESS );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/relaxation",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_LIMIT_RELAXATION );
+
+ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"motor/enable"),_SCS("set_flag"),_SCS("get_flag"), FLAG_ENABLE_MOTOR );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"motor/target_velocity",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_MOTOR_TARGET_VELOCITY );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"motor/max_impulse",PROPERTY_HINT_RANGE,"0.01,1024,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_MOTOR_MAX_IMPULSE);
+
+
+ BIND_CONSTANT( PARAM_BIAS );
+ BIND_CONSTANT( PARAM_LIMIT_UPPER );
+ BIND_CONSTANT( PARAM_LIMIT_LOWER );
+ BIND_CONSTANT( PARAM_LIMIT_BIAS );
+ BIND_CONSTANT( PARAM_LIMIT_SOFTNESS );
+ BIND_CONSTANT( PARAM_LIMIT_RELAXATION );
+ BIND_CONSTANT( PARAM_MOTOR_TARGET_VELOCITY );
+ BIND_CONSTANT( PARAM_MOTOR_MAX_IMPULSE );
+ BIND_CONSTANT( PARAM_MAX );
+
+ BIND_CONSTANT( FLAG_USE_LIMIT );
+ BIND_CONSTANT( FLAG_ENABLE_MOTOR );
+ BIND_CONSTANT( FLAG_MAX );
+
+}
+
+void HingeJoint::set_param(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->hinge_joint_set_param(get_joint(),PhysicsServer::HingeJointParam(p_param),p_value);
+
+ update_gizmo();
+
+}
+float HingeJoint::get_param(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params[p_param];
+}
+
+
+void HingeJoint::set_flag(Flag p_flag,bool p_value){
+
+ ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ flags[p_flag]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->hinge_joint_set_flag(get_joint(),PhysicsServer::HingeJointFlag(p_flag),p_value);
+
+ update_gizmo();
+}
+bool HingeJoint::get_flag(Flag p_flag) const{
+
+ ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+ return flags[p_flag];
+}
+
+RID HingeJoint::_configure_joint(PhysicsBody *body_a,PhysicsBody *body_b) {
+
+
+ Transform gt = get_global_transform();
+ Vector3 hingepos = gt.origin;
+ Vector3 hingedir = gt.basis.get_axis(2);
+
+ Transform ainv = body_a->get_global_transform().affine_inverse();
+
+ Transform local_a = ainv * gt;
+ local_a.orthonormalize();
+ Transform local_b = gt;
+
+ if (body_b) {
+ Transform binv = body_b->get_global_transform().affine_inverse();
+ local_b = binv * gt;
+ }
+
+ local_b.orthonormalize();
+
+ RID j = PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(),local_a,body_b?body_b->get_rid():RID(),local_b);
+ for(int i=0;i<PARAM_MAX;i++) {
+ PhysicsServer::get_singleton()->hinge_joint_set_param(j,PhysicsServer::HingeJointParam(i),params[i]);
+ }
+ for(int i=0;i<FLAG_MAX;i++) {
+ set_flag(Flag(i),flags[i]);
+ PhysicsServer::get_singleton()->hinge_joint_set_flag(j,PhysicsServer::HingeJointFlag(i),flags[i]);
+ }
+ return j;
+}
+
+
+HingeJoint::HingeJoint() {
+
+ params[PARAM_BIAS]=0.3;
+ params[PARAM_LIMIT_UPPER]=Math_PI*0.5;
+ params[PARAM_LIMIT_LOWER]=-Math_PI*0.5;
+ params[PARAM_LIMIT_BIAS]=0.3;
+ params[PARAM_LIMIT_SOFTNESS]=0.9;
+ params[PARAM_LIMIT_RELAXATION]=1.0;
+ params[PARAM_MOTOR_TARGET_VELOCITY]=1;
+ params[PARAM_MOTOR_MAX_IMPULSE]=1;
+
+
+ flags[FLAG_USE_LIMIT]=false;
+ flags[FLAG_ENABLE_MOTOR]=false;
+
+}
+
+
+
+
+/////////////////////////////////////////////////
+
+
+//////////////////////////////////
+
+
+
+void SliderJoint::_set_upper_limit_angular(float p_limit_angular) {
+
+ set_param(PARAM_ANGULAR_LIMIT_UPPER,Math::deg2rad(p_limit_angular));
+}
+
+float SliderJoint::_get_upper_limit_angular() const {
+
+ return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER));
+}
+
+void SliderJoint::_set_lower_limit_angular(float p_limit_angular) {
+
+ set_param(PARAM_ANGULAR_LIMIT_LOWER,Math::deg2rad(p_limit_angular));
+
+}
+
+float SliderJoint::_get_lower_limit_angular() const {
+
+ return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER));
+
+}
+
+
+void SliderJoint::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_param","param","value"),&SliderJoint::set_param);
+ ObjectTypeDB::bind_method(_MD("get_param","param"),&SliderJoint::get_param);
+
+
+ ObjectTypeDB::bind_method(_MD("_set_upper_limit_angular","upper_limit_angular"),&SliderJoint::_set_upper_limit_angular);
+ ObjectTypeDB::bind_method(_MD("_get_upper_limit_angular"),&SliderJoint::_get_upper_limit_angular);
+
+ ObjectTypeDB::bind_method(_MD("_set_lower_limit_angular","lower_limit_angular"),&SliderJoint::_set_lower_limit_angular);
+ ObjectTypeDB::bind_method(_MD("_get_lower_limit_angular"),&SliderJoint::_get_lower_limit_angular);
+
+
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_limit/upper_distance",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_LIMIT_UPPER);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_limit/lower_distance",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_LIMIT_LOWER);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_limit/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_limit/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_LIMIT_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_limit/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_LIMIT_DAMPING);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_motion/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_MOTION_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_motion/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_MOTION_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_motion/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_MOTION_DAMPING);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_ortho/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_ORTHOGONAL_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_ortho/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_ORTHOGONAL_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"linear_ortho/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_LINEAR_ORTHOGONAL_DAMPING);
+
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_limit/upper_angle",PROPERTY_HINT_RANGE,"-180,180,0.1"),_SCS("_set_upper_limit_angular"),_SCS("_get_upper_limit_angular") );
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_limit/lower_angle",PROPERTY_HINT_RANGE,"-180,180,0.1"),_SCS("_set_lower_limit_angular"),_SCS("_get_lower_limit_angular") );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_LIMIT_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_limit/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_LIMIT_DAMPING);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_motion/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_MOTION_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_motion/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_MOTION_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_motion/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_MOTION_DAMPING);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_ortho/softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_ORTHOGONAL_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_ortho/restitution",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_ORTHOGONAL_RESTITUTION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"angular_ortho/damping",PROPERTY_HINT_RANGE,"0,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_ANGULAR_ORTHOGONAL_DAMPING);
+
+
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_UPPER);
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_LOWER);
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_SOFTNESS);
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_RESTITUTION);
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_DAMPING);
+ BIND_CONSTANT( PARAM_LINEAR_MOTION_SOFTNESS);
+ BIND_CONSTANT( PARAM_LINEAR_MOTION_RESTITUTION);
+ BIND_CONSTANT( PARAM_LINEAR_MOTION_DAMPING);
+ BIND_CONSTANT( PARAM_LINEAR_ORTHOGONAL_SOFTNESS);
+ BIND_CONSTANT( PARAM_LINEAR_ORTHOGONAL_RESTITUTION);
+ BIND_CONSTANT( PARAM_LINEAR_ORTHOGONAL_DAMPING);
+
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_UPPER);
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_LOWER);
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_SOFTNESS);
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_RESTITUTION);
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_DAMPING);
+ BIND_CONSTANT( PARAM_ANGULAR_MOTION_SOFTNESS);
+ BIND_CONSTANT( PARAM_ANGULAR_MOTION_RESTITUTION);
+ BIND_CONSTANT( PARAM_ANGULAR_MOTION_DAMPING);
+ BIND_CONSTANT( PARAM_ANGULAR_ORTHOGONAL_SOFTNESS);
+ BIND_CONSTANT( PARAM_ANGULAR_ORTHOGONAL_RESTITUTION);
+ BIND_CONSTANT( PARAM_ANGULAR_ORTHOGONAL_DAMPING);
+
+ BIND_CONSTANT( PARAM_MAX);
+}
+
+void SliderJoint::set_param(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->slider_joint_set_param(get_joint(),PhysicsServer::SliderJointParam(p_param),p_value);
+ update_gizmo();
+
+}
+float SliderJoint::get_param(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params[p_param];
+}
+
+
+RID SliderJoint::_configure_joint(PhysicsBody *body_a,PhysicsBody *body_b) {
+
+
+ Transform gt = get_global_transform();
+ Vector3 sliderpos = gt.origin;
+ Vector3 sliderdir = gt.basis.get_axis(2);
+
+ Transform ainv = body_a->get_global_transform().affine_inverse();
+
+ Transform local_a = ainv * gt;
+ local_a.orthonormalize();
+ Transform local_b = gt;
+
+ if (body_b) {
+ Transform binv = body_b->get_global_transform().affine_inverse();
+ local_b = binv * gt;
+ }
+
+ local_b.orthonormalize();
+
+ RID j = PhysicsServer::get_singleton()->joint_create_slider(body_a->get_rid(),local_a,body_b?body_b->get_rid():RID(),local_b);
+ for(int i=0;i<PARAM_MAX;i++) {
+ PhysicsServer::get_singleton()->slider_joint_set_param(j,PhysicsServer::SliderJointParam(i),params[i]);
+ }
+
+ return j;
+}
+
+
+SliderJoint::SliderJoint() {
+
+
+
+ params[ PARAM_LINEAR_LIMIT_UPPER ]=1.0;
+ params[ PARAM_LINEAR_LIMIT_LOWER ]=-1.0;
+ params[ PARAM_LINEAR_LIMIT_SOFTNESS ]=1.0;
+ params[ PARAM_LINEAR_LIMIT_RESTITUTION]=0.7;
+ params[ PARAM_LINEAR_LIMIT_DAMPING]=1.0;
+ params[ PARAM_LINEAR_MOTION_SOFTNESS ]=1.0;
+ params[ PARAM_LINEAR_MOTION_RESTITUTION]=0.7;
+ params[ PARAM_LINEAR_MOTION_DAMPING]=0;//1.0;
+ params[ PARAM_LINEAR_ORTHOGONAL_SOFTNESS ]=1.0;
+ params[ PARAM_LINEAR_ORTHOGONAL_RESTITUTION]=0.7;
+ params[ PARAM_LINEAR_ORTHOGONAL_DAMPING]=1.0;
+
+ params[ PARAM_ANGULAR_LIMIT_UPPER ]=0 ;
+ params[ PARAM_ANGULAR_LIMIT_LOWER ]=0 ;
+ params[ PARAM_ANGULAR_LIMIT_SOFTNESS ]=1.0;
+ params[ PARAM_ANGULAR_LIMIT_RESTITUTION]=0.7;
+ params[ PARAM_ANGULAR_LIMIT_DAMPING]=0;//1.0;
+ params[ PARAM_ANGULAR_MOTION_SOFTNESS ]=1.0;
+ params[ PARAM_ANGULAR_MOTION_RESTITUTION]=0.7;
+ params[ PARAM_ANGULAR_MOTION_DAMPING]=1.0;
+ params[ PARAM_ANGULAR_ORTHOGONAL_SOFTNESS ]=1.0;
+ params[ PARAM_ANGULAR_ORTHOGONAL_RESTITUTION]=0.7;
+ params[ PARAM_ANGULAR_ORTHOGONAL_DAMPING]=1.0;
+}
+
+
+
+//////////////////////////////////
+
+
+
+void ConeTwistJoint::_set_swing_span(float p_limit_angular) {
+
+ set_param(PARAM_SWING_SPAN,Math::deg2rad(p_limit_angular));
+}
+
+float ConeTwistJoint::_get_swing_span() const {
+
+ return Math::rad2deg(get_param(PARAM_SWING_SPAN));
+}
+
+void ConeTwistJoint::_set_twist_span(float p_limit_angular) {
+
+ set_param(PARAM_TWIST_SPAN,Math::deg2rad(p_limit_angular));
+
+}
+
+float ConeTwistJoint::_get_twist_span() const {
+
+ return Math::rad2deg(get_param(PARAM_TWIST_SPAN));
+
+}
+
+
+void ConeTwistJoint::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_param","param","value"),&ConeTwistJoint::set_param);
+ ObjectTypeDB::bind_method(_MD("get_param","param"),&ConeTwistJoint::get_param);
+
+
+ ObjectTypeDB::bind_method(_MD("_set_swing_span","swing_span"),&ConeTwistJoint::_set_swing_span);
+ ObjectTypeDB::bind_method(_MD("_get_swing_span"),&ConeTwistJoint::_get_swing_span);
+
+ ObjectTypeDB::bind_method(_MD("_set_twist_span","twist_span"),&ConeTwistJoint::_set_twist_span);
+ ObjectTypeDB::bind_method(_MD("_get_twist_span"),&ConeTwistJoint::_get_twist_span);
+
+
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"swing_span",PROPERTY_HINT_RANGE,"-180,180,0.1"),_SCS("_set_swing_span"),_SCS("_get_swing_span") );
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"twist_span",PROPERTY_HINT_RANGE,"-40000,40000,0.1"),_SCS("_set_twist_span"),_SCS("_get_twist_span") );
+
+
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bias",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_BIAS );
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"softness",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_SOFTNESS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"relaxation",PROPERTY_HINT_RANGE,"0.01,16.0,0.01") ,_SCS("set_param"),_SCS("get_param"), PARAM_RELAXATION);
+
+ BIND_CONSTANT( PARAM_SWING_SPAN );
+ BIND_CONSTANT( PARAM_TWIST_SPAN );
+ BIND_CONSTANT( PARAM_BIAS );
+ BIND_CONSTANT( PARAM_SOFTNESS );
+ BIND_CONSTANT( PARAM_RELAXATION );
+ BIND_CONSTANT( PARAM_MAX );
+}
+
+void ConeTwistJoint::set_param(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->cone_twist_joint_set_param(get_joint(),PhysicsServer::ConeTwistJointParam(p_param),p_value);
+
+ update_gizmo();
+}
+float ConeTwistJoint::get_param(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params[p_param];
+}
+
+
+RID ConeTwistJoint::_configure_joint(PhysicsBody *body_a,PhysicsBody *body_b) {
+
+
+ Transform gt = get_global_transform();
+ //Vector3 cone_twistpos = gt.origin;
+ //Vector3 cone_twistdir = gt.basis.get_axis(2);
+
+ Transform ainv = body_a->get_global_transform().affine_inverse();
+
+ Transform local_a = ainv * gt;
+ local_a.orthonormalize();
+ Transform local_b = gt;
+
+ if (body_b) {
+ Transform binv = body_b->get_global_transform().affine_inverse();
+ local_b = binv * gt;
+ }
+
+ local_b.orthonormalize();
+
+ RID j = PhysicsServer::get_singleton()->joint_create_cone_twist(body_a->get_rid(),local_a,body_b?body_b->get_rid():RID(),local_b);
+ for(int i=0;i<PARAM_MAX;i++) {
+ PhysicsServer::get_singleton()->cone_twist_joint_set_param(j,PhysicsServer::ConeTwistJointParam(i),params[i]);
+ }
+
+ return j;
+}
+
+
+ConeTwistJoint::ConeTwistJoint() {
+
+
+ params[ PARAM_SWING_SPAN ]=Math_PI*0.25;
+ params[ PARAM_TWIST_SPAN ]=Math_PI;
+ params[ PARAM_BIAS ]=0.3;
+ params[ PARAM_SOFTNESS ]=0.8;
+ params[ PARAM_RELAXATION ]=1.0;
+
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+void Generic6DOFJoint::_set_angular_hi_limit_x(float p_limit_angular) {
+
+ set_param_x(PARAM_ANGULAR_UPPER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_hi_limit_x() const{
+
+ return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT));
+
+}
+
+void Generic6DOFJoint::_set_angular_lo_limit_x(float p_limit_angular) {
+
+ set_param_x(PARAM_ANGULAR_LOWER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_lo_limit_x() const{
+
+ return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT));
+
+}
+
+
+void Generic6DOFJoint::_set_angular_hi_limit_y(float p_limit_angular) {
+
+ set_param_y(PARAM_ANGULAR_UPPER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_hi_limit_y() const{
+
+ return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT));
+
+}
+
+void Generic6DOFJoint::_set_angular_lo_limit_y(float p_limit_angular) {
+
+ set_param_y(PARAM_ANGULAR_LOWER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_lo_limit_y() const{
+
+ return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT));
+
+}
+
+
+void Generic6DOFJoint::_set_angular_hi_limit_z(float p_limit_angular) {
+
+ set_param_z(PARAM_ANGULAR_UPPER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_hi_limit_z() const{
+
+ return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT));
+
+}
+
+void Generic6DOFJoint::_set_angular_lo_limit_z(float p_limit_angular) {
+
+ set_param_z(PARAM_ANGULAR_LOWER_LIMIT,Math::deg2rad(p_limit_angular));
+}
+
+float Generic6DOFJoint::_get_angular_lo_limit_z() const{
+
+ return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT));
+
+}
+
+
+
+void Generic6DOFJoint::_bind_methods(){
+
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_hi_limit_x","angle"),&Generic6DOFJoint::_set_angular_hi_limit_x);
+ ObjectTypeDB::bind_method(_MD("_get_angular_hi_limit_x"),&Generic6DOFJoint::_get_angular_hi_limit_x);
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_lo_limit_x","angle"),&Generic6DOFJoint::_set_angular_lo_limit_x);
+ ObjectTypeDB::bind_method(_MD("_get_angular_lo_limit_x"),&Generic6DOFJoint::_get_angular_lo_limit_x);
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_hi_limit_y","angle"),&Generic6DOFJoint::_set_angular_hi_limit_y);
+ ObjectTypeDB::bind_method(_MD("_get_angular_hi_limit_y"),&Generic6DOFJoint::_get_angular_hi_limit_y);
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_lo_limit_y","angle"),&Generic6DOFJoint::_set_angular_lo_limit_y);
+ ObjectTypeDB::bind_method(_MD("_get_angular_lo_limit_y"),&Generic6DOFJoint::_get_angular_lo_limit_y);
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_hi_limit_z","angle"),&Generic6DOFJoint::_set_angular_hi_limit_z);
+ ObjectTypeDB::bind_method(_MD("_get_angular_hi_limit_z"),&Generic6DOFJoint::_get_angular_hi_limit_z);
+
+ ObjectTypeDB::bind_method(_MD("_set_angular_lo_limit_z","angle"),&Generic6DOFJoint::_set_angular_lo_limit_z);
+ ObjectTypeDB::bind_method(_MD("_get_angular_lo_limit_z"),&Generic6DOFJoint::_get_angular_lo_limit_z);
+
+ ObjectTypeDB::bind_method(_MD("set_param_x","param","value"),&Generic6DOFJoint::set_param_x);
+ ObjectTypeDB::bind_method(_MD("get_param_x","param"),&Generic6DOFJoint::get_param_x);
+
+ ObjectTypeDB::bind_method(_MD("set_param_y","param","value"),&Generic6DOFJoint::set_param_y);
+ ObjectTypeDB::bind_method(_MD("get_param_y","param"),&Generic6DOFJoint::get_param_y);
+
+ ObjectTypeDB::bind_method(_MD("set_param_z","param","value"),&Generic6DOFJoint::set_param_z);
+ ObjectTypeDB::bind_method(_MD("get_param_z","param"),&Generic6DOFJoint::get_param_z);
+
+ ObjectTypeDB::bind_method(_MD("set_flag_x","flag","value"),&Generic6DOFJoint::set_flag_x);
+ ObjectTypeDB::bind_method(_MD("get_flag_x","flag"),&Generic6DOFJoint::get_flag_x);
+
+ ObjectTypeDB::bind_method(_MD("set_flag_y","flag","value"),&Generic6DOFJoint::set_flag_y);
+ ObjectTypeDB::bind_method(_MD("get_flag_y","flag"),&Generic6DOFJoint::get_flag_y);
+
+ ObjectTypeDB::bind_method(_MD("set_flag_z","flag","value"),&Generic6DOFJoint::set_flag_z);
+ ObjectTypeDB::bind_method(_MD("get_flag_z","flag"),&Generic6DOFJoint::get_flag_z);
+
+
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"linear_limit_x/enabled"),_SCS("set_flag_x"),_SCS("get_flag_x"),FLAG_ENABLE_LINEAR_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_x/upper_distance"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_LINEAR_UPPER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_x/lower_distance"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_LINEAR_LOWER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_x/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_LINEAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_x/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_LINEAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_x/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_LINEAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_limit_x/enabled"),_SCS("set_flag_x"),_SCS("get_flag_x"),FLAG_ENABLE_ANGULAR_LIMIT);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_x/upper_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_hi_limit_x"),_SCS("_get_angular_hi_limit_x"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_x/lower_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_lo_limit_x"),_SCS("_get_angular_lo_limit_x"));
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_x/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_x/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_x/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_x/force_limit"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_FORCE_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_x/erp"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_ERP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_motor_x/enabled"),_SCS("set_flag_x"),_SCS("get_flag_x"),FLAG_ENABLE_MOTOR);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_x/target_velocity"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_x/force_limit"),_SCS("set_param_x"),_SCS("get_param_x"),PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
+
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"linear_limit_y/enabled"),_SCS("set_flag_y"),_SCS("get_flag_y"),FLAG_ENABLE_LINEAR_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_y/upper_distance"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_LINEAR_UPPER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_y/lower_distance"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_LINEAR_LOWER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_y/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_LINEAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_y/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_LINEAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_y/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_LINEAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_limit_y/enabled"),_SCS("set_flag_y"),_SCS("get_flag_y"),FLAG_ENABLE_ANGULAR_LIMIT);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_y/upper_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_hi_limit_y"),_SCS("_get_angular_hi_limit_y"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_y/lower_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_lo_limit_y"),_SCS("_get_angular_lo_limit_y"));
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_y/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_y/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_y/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_y/force_limit"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_FORCE_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_y/erp"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_ERP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_motor_y/enabled"),_SCS("set_flag_y"),_SCS("get_flag_y"),FLAG_ENABLE_MOTOR);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_y/target_velocity"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_y/force_limit"),_SCS("set_param_y"),_SCS("get_param_y"),PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
+
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"linear_limit_z/enabled"),_SCS("set_flag_z"),_SCS("get_flag_z"),FLAG_ENABLE_LINEAR_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_z/upper_distance"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_LINEAR_UPPER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_z/lower_distance"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_LINEAR_LOWER_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_z/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_LINEAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_z/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_LINEAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"linear_limit_z/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_LINEAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_limit_z/enabled"),_SCS("set_flag_z"),_SCS("get_flag_z"),FLAG_ENABLE_ANGULAR_LIMIT);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_z/upper_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_hi_limit_z"),_SCS("_get_angular_hi_limit_z"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"angular_limit_z/lower_angle",PROPERTY_HINT_RANGE,"-180,180,0.01"),_SCS("_set_angular_lo_limit_z"),_SCS("_get_angular_lo_limit_z"));
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_z/softness",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_LIMIT_SOFTNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_z/restitution",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_RESTITUTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_z/damping",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_z/force_limit"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_FORCE_LIMIT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_limit_z/erp"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_ERP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"angular_motor_z/enabled"),_SCS("set_flag_z"),_SCS("get_flag_z"),FLAG_ENABLE_MOTOR);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_z/target_velocity"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL,"angular_motor_z/force_limit"),_SCS("set_param_z"),_SCS("get_param_z"),PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
+
+
+ BIND_CONSTANT( PARAM_LINEAR_LOWER_LIMIT);
+ BIND_CONSTANT( PARAM_LINEAR_UPPER_LIMIT);
+ BIND_CONSTANT( PARAM_LINEAR_LIMIT_SOFTNESS);
+ BIND_CONSTANT( PARAM_LINEAR_RESTITUTION);
+ BIND_CONSTANT( PARAM_LINEAR_DAMPING);
+ BIND_CONSTANT( PARAM_ANGULAR_LOWER_LIMIT);
+ BIND_CONSTANT( PARAM_ANGULAR_UPPER_LIMIT);
+ BIND_CONSTANT( PARAM_ANGULAR_LIMIT_SOFTNESS);
+ BIND_CONSTANT( PARAM_ANGULAR_DAMPING);
+ BIND_CONSTANT( PARAM_ANGULAR_RESTITUTION);
+ BIND_CONSTANT( PARAM_ANGULAR_FORCE_LIMIT);
+ BIND_CONSTANT( PARAM_ANGULAR_ERP);
+ BIND_CONSTANT( PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
+ BIND_CONSTANT( PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
+ BIND_CONSTANT( PARAM_MAX);
+
+ BIND_CONSTANT( FLAG_ENABLE_LINEAR_LIMIT);
+ BIND_CONSTANT( FLAG_ENABLE_ANGULAR_LIMIT);
+ BIND_CONSTANT( FLAG_ENABLE_MOTOR);
+ BIND_CONSTANT( FLAG_MAX );
+}
+
+
+void Generic6DOFJoint::set_param_x(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params_x[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(get_joint(),Vector3::AXIS_X,PhysicsServer::G6DOFJointAxisParam(p_param),p_value);
+
+ update_gizmo();
+}
+float Generic6DOFJoint::get_param_x(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params_x[p_param];
+}
+
+void Generic6DOFJoint::set_param_y(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params_y[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(get_joint(),Vector3::AXIS_Y,PhysicsServer::G6DOFJointAxisParam(p_param),p_value);
+ update_gizmo();
+
+}
+float Generic6DOFJoint::get_param_y(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params_y[p_param];
+}
+
+
+void Generic6DOFJoint::set_param_z(Param p_param,float p_value){
+
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params_z[p_param]=p_value;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(get_joint(),Vector3::AXIS_Z,PhysicsServer::G6DOFJointAxisParam(p_param),p_value);
+ update_gizmo();
+}
+float Generic6DOFJoint::get_param_z(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params_z[p_param];
+}
+
+
+void Generic6DOFJoint::set_flag_x(Flag p_flag,bool p_enabled){
+
+ ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ flags_x[p_flag]=p_enabled;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(get_joint(),Vector3::AXIS_X,PhysicsServer::G6DOFJointAxisFlag(p_flag),p_enabled);
+ update_gizmo();
+
+}
+bool Generic6DOFJoint::get_flag_x(Flag p_flag) const{
+
+ ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+ return flags_x[p_flag];
+
+}
+
+void Generic6DOFJoint::set_flag_y(Flag p_flag,bool p_enabled){
+
+ ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ flags_y[p_flag]=p_enabled;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(get_joint(),Vector3::AXIS_Y,PhysicsServer::G6DOFJointAxisFlag(p_flag),p_enabled);
+ update_gizmo();
+}
+bool Generic6DOFJoint::get_flag_y(Flag p_flag) const{
+
+ ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+ return flags_y[p_flag];
+
+}
+
+void Generic6DOFJoint::set_flag_z(Flag p_flag,bool p_enabled){
+
+ ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ flags_z[p_flag]=p_enabled;
+ if (get_joint().is_valid())
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(get_joint(),Vector3::AXIS_Z,PhysicsServer::G6DOFJointAxisFlag(p_flag),p_enabled);
+ update_gizmo();
+}
+bool Generic6DOFJoint::get_flag_z(Flag p_flag) const{
+
+ ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+ return flags_z[p_flag];
+
+}
+
+RID Generic6DOFJoint::_configure_joint(PhysicsBody *body_a,PhysicsBody *body_b) {
+
+
+ Transform gt = get_global_transform();
+ //Vector3 cone_twistpos = gt.origin;
+ //Vector3 cone_twistdir = gt.basis.get_axis(2);
+
+ Transform ainv = body_a->get_global_transform().affine_inverse();
+
+ Transform local_a = ainv * gt;
+ local_a.orthonormalize();
+ Transform local_b = gt;
+
+ if (body_b) {
+ Transform binv = body_b->get_global_transform().affine_inverse();
+ local_b = binv * gt;
+ }
+
+ local_b.orthonormalize();
+
+ RID j = PhysicsServer::get_singleton()->joint_create_generic_6dof(body_a->get_rid(),local_a,body_b?body_b->get_rid():RID(),local_b);
+ for(int i=0;i<PARAM_MAX;i++) {
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j,Vector3::AXIS_X,PhysicsServer::G6DOFJointAxisParam(i),params_x[i]);
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j,Vector3::AXIS_Y,PhysicsServer::G6DOFJointAxisParam(i),params_y[i]);
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j,Vector3::AXIS_Z,PhysicsServer::G6DOFJointAxisParam(i),params_z[i]);
+ }
+ for(int i=0;i<FLAG_MAX;i++) {
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j,Vector3::AXIS_X,PhysicsServer::G6DOFJointAxisFlag(i),flags_x[i]);
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j,Vector3::AXIS_Y,PhysicsServer::G6DOFJointAxisFlag(i),flags_y[i]);
+ PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j,Vector3::AXIS_Z,PhysicsServer::G6DOFJointAxisFlag(i),flags_z[i]);
+ }
+
+ return j;
+}
+
+
+Generic6DOFJoint::Generic6DOFJoint() {
+
+ set_param_x( PARAM_LINEAR_LOWER_LIMIT,0);
+ set_param_x( PARAM_LINEAR_UPPER_LIMIT,0);
+ set_param_x( PARAM_LINEAR_LIMIT_SOFTNESS,0.7);
+ set_param_x( PARAM_LINEAR_RESTITUTION,0.5);
+ set_param_x( PARAM_LINEAR_DAMPING,1.0);
+ set_param_x( PARAM_ANGULAR_LOWER_LIMIT,0);
+ set_param_x( PARAM_ANGULAR_UPPER_LIMIT,0);
+ set_param_x( PARAM_ANGULAR_LIMIT_SOFTNESS,0.5f);
+ set_param_x( PARAM_ANGULAR_DAMPING,1.0f);
+ set_param_x( PARAM_ANGULAR_RESTITUTION,0);
+ set_param_x( PARAM_ANGULAR_FORCE_LIMIT,0);
+ set_param_x( PARAM_ANGULAR_ERP,0.5);
+ set_param_x( PARAM_ANGULAR_MOTOR_TARGET_VELOCITY,0);
+ set_param_x( PARAM_ANGULAR_MOTOR_FORCE_LIMIT,300);
+
+ set_flag_x( FLAG_ENABLE_ANGULAR_LIMIT,true);
+ set_flag_x( FLAG_ENABLE_LINEAR_LIMIT,true);
+ set_flag_x( FLAG_ENABLE_MOTOR,false);
+
+ set_param_y( PARAM_LINEAR_LOWER_LIMIT,0);
+ set_param_y( PARAM_LINEAR_UPPER_LIMIT,0);
+ set_param_y( PARAM_LINEAR_LIMIT_SOFTNESS,0.7);
+ set_param_y( PARAM_LINEAR_RESTITUTION,0.5);
+ set_param_y( PARAM_LINEAR_DAMPING,1.0);
+ set_param_y( PARAM_ANGULAR_LOWER_LIMIT,0);
+ set_param_y( PARAM_ANGULAR_UPPER_LIMIT,0);
+ set_param_y( PARAM_ANGULAR_LIMIT_SOFTNESS,0.5f);
+ set_param_y( PARAM_ANGULAR_DAMPING,1.0f);
+ set_param_y( PARAM_ANGULAR_RESTITUTION,0);
+ set_param_y( PARAM_ANGULAR_FORCE_LIMIT,0);
+ set_param_y( PARAM_ANGULAR_ERP,0.5);
+ set_param_y( PARAM_ANGULAR_MOTOR_TARGET_VELOCITY,0);
+ set_param_y( PARAM_ANGULAR_MOTOR_FORCE_LIMIT,300);
+
+ set_flag_y( FLAG_ENABLE_ANGULAR_LIMIT,true);
+ set_flag_y( FLAG_ENABLE_LINEAR_LIMIT,true);
+ set_flag_y( FLAG_ENABLE_MOTOR,false);
+
+
+ set_param_z( PARAM_LINEAR_LOWER_LIMIT,0);
+ set_param_z( PARAM_LINEAR_UPPER_LIMIT,0);
+ set_param_z( PARAM_LINEAR_LIMIT_SOFTNESS,0.7);
+ set_param_z( PARAM_LINEAR_RESTITUTION,0.5);
+ set_param_z( PARAM_LINEAR_DAMPING,1.0);
+ set_param_z( PARAM_ANGULAR_LOWER_LIMIT,0);
+ set_param_z( PARAM_ANGULAR_UPPER_LIMIT,0);
+ set_param_z( PARAM_ANGULAR_LIMIT_SOFTNESS,0.5f);
+ set_param_z( PARAM_ANGULAR_DAMPING,1.0f);
+ set_param_z( PARAM_ANGULAR_RESTITUTION,0);
+ set_param_z( PARAM_ANGULAR_FORCE_LIMIT,0);
+ set_param_z( PARAM_ANGULAR_ERP,0.5);
+ set_param_z( PARAM_ANGULAR_MOTOR_TARGET_VELOCITY,0);
+ set_param_z( PARAM_ANGULAR_MOTOR_FORCE_LIMIT,300);
+
+ set_flag_z( FLAG_ENABLE_ANGULAR_LIMIT,true);
+ set_flag_z( FLAG_ENABLE_LINEAR_LIMIT,true);
+ set_flag_z( FLAG_ENABLE_MOTOR,false);
+
+}
+
+
+
+
#if 0
void PhysicsJoint::_set(const String& p_name, const Variant& p_value) {
diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h
index 4a0c609e69..6daa06da2b 100644
--- a/scene/3d/physics_joint.h
+++ b/scene/3d/physics_joint.h
@@ -32,6 +32,313 @@
#include "scene/3d/spatial.h"
#include "scene/3d/physics_body.h"
+
+class Joint : public Spatial {
+
+ OBJ_TYPE(Joint,Spatial);
+
+ RID ba,bb;
+
+ RID joint;
+
+ NodePath a;
+ NodePath b;
+
+
+protected:
+
+ void _update_joint(bool p_only_free=false);
+
+ void _notification(int p_what);
+
+ virtual RID _configure_joint(PhysicsBody *body_a,PhysicsBody *body_b)=0;
+
+ static void _bind_methods();
+public:
+
+ void set_node_a(const NodePath& p_node_a);
+ NodePath get_node_a() const;
+
+ void set_node_b(const NodePath& p_node_b);
+ NodePath get_node_b() const;
+
+ RID get_joint() const { return joint; }
+ Joint();
+
+};
+
+///////////////////////////////////////////
+
+
+class PinJoint : public Joint {
+
+ OBJ_TYPE(PinJoint,Joint);
+public:
+
+ enum Param {
+ PARAM_BIAS=PhysicsServer::PIN_JOINT_BIAS,
+ PARAM_DAMPING=PhysicsServer::PIN_JOINT_DAMPING,
+ PARAM_IMPULSE_CLAMP=PhysicsServer::PIN_JOINT_IMPULSE_CLAMP
+ };
+
+protected:
+
+ float params[3];
+ virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
+ static void _bind_methods();
+public:
+
+ void set_param(Param p_param,float p_value);
+ float get_param(Param p_param) const;
+
+ PinJoint();
+};
+
+VARIANT_ENUM_CAST(PinJoint::Param);
+
+
+class HingeJoint : public Joint {
+
+ OBJ_TYPE(HingeJoint,Joint);
+public:
+
+ enum Param {
+ PARAM_BIAS=PhysicsServer::HINGE_JOINT_BIAS,
+ PARAM_LIMIT_UPPER=PhysicsServer::HINGE_JOINT_LIMIT_UPPER,
+ PARAM_LIMIT_LOWER=PhysicsServer::HINGE_JOINT_LIMIT_LOWER,
+ PARAM_LIMIT_BIAS=PhysicsServer::HINGE_JOINT_LIMIT_BIAS,
+ PARAM_LIMIT_SOFTNESS=PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS,
+ PARAM_LIMIT_RELAXATION=PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION,
+ PARAM_MOTOR_TARGET_VELOCITY=PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY,
+ PARAM_MOTOR_MAX_IMPULSE=PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE,
+ PARAM_MAX=PhysicsServer::HINGE_JOINT_MAX
+ };
+
+ enum Flag {
+ FLAG_USE_LIMIT=PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT,
+ FLAG_ENABLE_MOTOR=PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR,
+ FLAG_MAX=PhysicsServer::HINGE_JOINT_FLAG_MAX
+ };
+
+
+
+protected:
+
+ float params[PARAM_MAX];
+ bool flags[FLAG_MAX];
+ virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
+ static void _bind_methods();
+
+ void _set_upper_limit(float p_limit);
+ float _get_upper_limit() const;
+
+ void _set_lower_limit(float p_limit);
+ float _get_lower_limit() const;
+
+public:
+
+ void set_param(Param p_param,float p_value);
+ float get_param(Param p_param) const;
+
+ void set_flag(Flag p_flag,bool p_value);
+ bool get_flag(Flag p_flag) const;
+
+ HingeJoint();
+};
+
+VARIANT_ENUM_CAST(HingeJoint::Param);
+VARIANT_ENUM_CAST(HingeJoint::Flag);
+
+
+class SliderJoint : public Joint {
+
+ OBJ_TYPE(SliderJoint,Joint);
+public:
+
+ enum Param {
+ PARAM_LINEAR_LIMIT_UPPER=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER,
+ PARAM_LINEAR_LIMIT_LOWER=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER,
+ PARAM_LINEAR_LIMIT_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS,
+ PARAM_LINEAR_LIMIT_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION,
+ PARAM_LINEAR_LIMIT_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING,
+ PARAM_LINEAR_MOTION_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS,
+ PARAM_LINEAR_MOTION_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION,
+ PARAM_LINEAR_MOTION_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING,
+ PARAM_LINEAR_ORTHOGONAL_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS,
+ PARAM_LINEAR_ORTHOGONAL_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION,
+ PARAM_LINEAR_ORTHOGONAL_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING,
+
+ PARAM_ANGULAR_LIMIT_UPPER=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER,
+ PARAM_ANGULAR_LIMIT_LOWER=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER,
+ PARAM_ANGULAR_LIMIT_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS,
+ PARAM_ANGULAR_LIMIT_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION,
+ PARAM_ANGULAR_LIMIT_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING,
+ PARAM_ANGULAR_MOTION_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS,
+ PARAM_ANGULAR_MOTION_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION,
+ PARAM_ANGULAR_MOTION_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING,
+ PARAM_ANGULAR_ORTHOGONAL_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS,
+ PARAM_ANGULAR_ORTHOGONAL_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION,
+ PARAM_ANGULAR_ORTHOGONAL_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING,
+ PARAM_MAX=PhysicsServer::SLIDER_JOINT_MAX
+
+ };
+
+protected:
+
+
+
+ void _set_upper_limit_angular(float p_limit_angular);
+ float _get_upper_limit_angular() const;
+
+ void _set_lower_limit_angular(float p_limit_angular);
+ float _get_lower_limit_angular() const;
+
+ float params[PARAM_MAX];
+ virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
+ static void _bind_methods();
+public:
+
+ void set_param(Param p_param,float p_value);
+ float get_param(Param p_param) const;
+
+ SliderJoint();
+};
+
+
+VARIANT_ENUM_CAST(SliderJoint::Param);
+
+
+
+
+class ConeTwistJoint : public Joint {
+
+ OBJ_TYPE(ConeTwistJoint,Joint);
+public:
+
+ enum Param {
+
+ PARAM_SWING_SPAN,
+ PARAM_TWIST_SPAN,
+ PARAM_BIAS,
+ PARAM_SOFTNESS,
+ PARAM_RELAXATION,
+ PARAM_MAX
+ };
+
+protected:
+
+
+ void _set_swing_span(float p_limit_angular);
+ float _get_swing_span() const;
+
+ void _set_twist_span(float p_limit_angular);
+ float _get_twist_span() const;
+
+ float params[PARAM_MAX];
+ virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
+ static void _bind_methods();
+public:
+
+ void set_param(Param p_param,float p_value);
+ float get_param(Param p_param) const;
+
+ ConeTwistJoint();
+};
+
+
+VARIANT_ENUM_CAST(ConeTwistJoint::Param);
+
+
+class Generic6DOFJoint : public Joint {
+
+ OBJ_TYPE(Generic6DOFJoint,Joint);
+public:
+
+ enum Param {
+
+ PARAM_LINEAR_LOWER_LIMIT=PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT,
+ PARAM_LINEAR_UPPER_LIMIT=PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT,
+ PARAM_LINEAR_LIMIT_SOFTNESS=PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS,
+ PARAM_LINEAR_RESTITUTION=PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION,
+ PARAM_LINEAR_DAMPING=PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING,
+ PARAM_ANGULAR_LOWER_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT,
+ PARAM_ANGULAR_UPPER_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT,
+ PARAM_ANGULAR_LIMIT_SOFTNESS=PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS,
+ PARAM_ANGULAR_DAMPING=PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING,
+ PARAM_ANGULAR_RESTITUTION=PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION,
+ PARAM_ANGULAR_FORCE_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_FORCE_LIMIT,
+ PARAM_ANGULAR_ERP=PhysicsServer::G6DOF_JOINT_ANGULAR_ERP,
+ PARAM_ANGULAR_MOTOR_TARGET_VELOCITY=PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY,
+ PARAM_ANGULAR_MOTOR_FORCE_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT,
+ PARAM_MAX=PhysicsServer::G6DOF_JOINT_MAX,
+ };
+
+ enum Flag {
+ FLAG_ENABLE_LINEAR_LIMIT=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT,
+ FLAG_ENABLE_ANGULAR_LIMIT=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT,
+ FLAG_ENABLE_MOTOR=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR,
+ FLAG_MAX=PhysicsServer::G6DOF_JOINT_FLAG_MAX
+ };
+
+
+protected:
+
+
+ void _set_angular_hi_limit_x(float p_limit_angular);
+ float _get_angular_hi_limit_x() const;
+
+ void _set_angular_hi_limit_y(float p_limit_angular);
+ float _get_angular_hi_limit_y() const;
+
+ void _set_angular_hi_limit_z(float p_limit_angular);
+ float _get_angular_hi_limit_z() const;
+
+ void _set_angular_lo_limit_x(float p_limit_angular);
+ float _get_angular_lo_limit_x() const;
+
+ void _set_angular_lo_limit_y(float p_limit_angular);
+ float _get_angular_lo_limit_y() const;
+
+ void _set_angular_lo_limit_z(float p_limit_angular);
+ float _get_angular_lo_limit_z() const;
+
+ float params_x[PARAM_MAX];
+ bool flags_x[FLAG_MAX];
+ float params_y[PARAM_MAX];
+ bool flags_y[FLAG_MAX];
+ float params_z[PARAM_MAX];
+ bool flags_z[FLAG_MAX];
+
+ virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
+ static void _bind_methods();
+public:
+
+ void set_param_x(Param p_param,float p_value);
+ float get_param_x(Param p_param) const;
+
+ void set_param_y(Param p_param,float p_value);
+ float get_param_y(Param p_param) const;
+
+ void set_param_z(Param p_param,float p_value);
+ float get_param_z(Param p_param) const;
+
+ void set_flag_x(Flag p_flag,bool p_enabled);
+ bool get_flag_x(Flag p_flag) const;
+
+ void set_flag_y(Flag p_flag,bool p_enabled);
+ bool get_flag_y(Flag p_flag) const;
+
+ void set_flag_z(Flag p_flag,bool p_enabled);
+ bool get_flag_z(Flag p_flag) const;
+
+ Generic6DOFJoint();
+};
+
+
+VARIANT_ENUM_CAST(Generic6DOFJoint::Param);
+VARIANT_ENUM_CAST(Generic6DOFJoint::Flag);
+
+
#if 0
class PhysicsJoint : public Spatial {
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 7680c1d56c..07abd1dcd2 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -125,19 +125,161 @@ void VehicleWheel::_update(PhysicsDirectBodyState *s) {
}
}
+void VehicleWheel::set_radius(float p_radius) {
+
+ m_wheelRadius=p_radius;
+ update_gizmo();
+}
+
+float VehicleWheel::get_radius() const{
+
+ return m_wheelRadius;
+}
+
+void VehicleWheel::set_suspension_rest_length(float p_length){
+
+ m_suspensionRestLength=p_length;
+ update_gizmo();
+}
+float VehicleWheel::get_suspension_rest_length() const{
+
+ return m_suspensionRestLength;
+}
+
+void VehicleWheel::set_suspension_travel(float p_length){
+
+ m_maxSuspensionTravelCm=p_length/0.01;
+}
+float VehicleWheel::get_suspension_travel() const{
+
+ return m_maxSuspensionTravelCm*0.01;
+}
+
+void VehicleWheel::set_suspension_stiffness(float p_value){
+
+ m_suspensionStiffness=p_value;
+}
+float VehicleWheel::get_suspension_stiffness() const{
+
+ return m_suspensionStiffness;
+}
+
+void VehicleWheel::set_suspension_max_force(float p_value){
+
+ m_maxSuspensionForce=p_value;
+}
+float VehicleWheel::get_suspension_max_force() const{
+
+ return m_maxSuspensionForce;
+}
+
+void VehicleWheel::set_damping_compression(float p_value){
+
+ m_wheelsDampingCompression=p_value;
+}
+float VehicleWheel::get_damping_compression() const{
+
+ return m_wheelsDampingRelaxation;
+}
+
+void VehicleWheel::set_damping_relaxation(float p_value){
+
+ m_wheelsDampingRelaxation=p_value;
+}
+float VehicleWheel::get_damping_relaxation() const{
+
+ return m_wheelsDampingRelaxation;
+}
+
+void VehicleWheel::set_friction_slip(float p_value) {
+
+ m_frictionSlip=p_value;
+}
+float VehicleWheel::get_friction_slip() const{
+
+ return m_frictionSlip;
+}
+
+
void VehicleWheel::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("set_radius","length"),&VehicleWheel::set_radius);
+ ObjectTypeDB::bind_method(_MD("get_radius"),&VehicleWheel::get_radius);
+
+ ObjectTypeDB::bind_method(_MD("set_suspension_rest_length","length"),&VehicleWheel::set_suspension_rest_length);
+ ObjectTypeDB::bind_method(_MD("get_suspension_rest_length"),&VehicleWheel::get_suspension_rest_length);
+
+ ObjectTypeDB::bind_method(_MD("set_suspension_travel","length"),&VehicleWheel::set_suspension_travel);
+ ObjectTypeDB::bind_method(_MD("get_suspension_travel"),&VehicleWheel::get_suspension_travel);
+
+ ObjectTypeDB::bind_method(_MD("set_suspension_stiffness","length"),&VehicleWheel::set_suspension_stiffness);
+ ObjectTypeDB::bind_method(_MD("get_suspension_stiffness"),&VehicleWheel::get_suspension_stiffness);
+
+ ObjectTypeDB::bind_method(_MD("set_suspension_max_force","length"),&VehicleWheel::set_suspension_max_force);
+ ObjectTypeDB::bind_method(_MD("get_suspension_max_force"),&VehicleWheel::get_suspension_max_force);
+
+ ObjectTypeDB::bind_method(_MD("set_damping_compression","length"),&VehicleWheel::set_damping_compression);
+ ObjectTypeDB::bind_method(_MD("get_damping_compression"),&VehicleWheel::get_damping_compression);
+
+ ObjectTypeDB::bind_method(_MD("set_damping_relaxation","length"),&VehicleWheel::set_damping_relaxation);
+ ObjectTypeDB::bind_method(_MD("get_damping_relaxation"),&VehicleWheel::get_damping_relaxation);
+
+ ObjectTypeDB::bind_method(_MD("set_use_as_traction","enable"),&VehicleWheel::set_use_as_traction);
+ ObjectTypeDB::bind_method(_MD("is_used_as_traction"),&VehicleWheel::is_used_as_traction);
+
+ ObjectTypeDB::bind_method(_MD("set_use_as_steering","enable"),&VehicleWheel::set_use_as_steering);
+ ObjectTypeDB::bind_method(_MD("is_used_as_steering"),&VehicleWheel::is_used_as_steering);
+
+ ObjectTypeDB::bind_method(_MD("set_friction_slip","length"),&VehicleWheel::set_friction_slip);
+ ObjectTypeDB::bind_method(_MD("get_friction_slip"),&VehicleWheel::get_friction_slip);
+
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"type/traction"),_SCS("set_use_as_traction"),_SCS("is_used_as_traction"));
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"type/steering"),_SCS("set_use_as_steering"),_SCS("is_used_as_steering"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"wheel/radius"),_SCS("set_radius"),_SCS("get_radius"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"wheel/rest_length"),_SCS("set_suspension_rest_length"),_SCS("get_suspension_rest_length"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"wheel/friction_slip"),_SCS("set_friction_slip"),_SCS("get_friction_slip"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"suspension/travel"),_SCS("set_suspension_travel"),_SCS("get_suspension_travel"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"suspension/stiffness"),_SCS("set_suspension_stiffness"),_SCS("get_suspension_stiffness"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"suspension/max_force"),_SCS("set_suspension_max_force"),_SCS("get_suspension_max_force"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"damping/compression"),_SCS("set_damping_compression"),_SCS("get_damping_compression"));
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"damping/relaxation"),_SCS("set_damping_relaxation"),_SCS("get_damping_relaxation"));
+
+}
+
+
+void VehicleWheel::set_use_as_traction(bool p_enable) {
+
+ engine_traction=p_enable;
+}
+
+bool VehicleWheel::is_used_as_traction() const{
+
+ return engine_traction;
+}
+
+
+void VehicleWheel::set_use_as_steering(bool p_enabled){
+
+ steers=p_enabled;
+}
+
+bool VehicleWheel::is_used_as_steering() const{
+
+ return steers;
}
VehicleWheel::VehicleWheel() {
+ steers=false;
+ engine_traction=false;
m_steering = real_t(0.);
- m_engineForce = real_t(0.);
+ //m_engineForce = real_t(0.);
m_rotation = real_t(0.);
m_deltaRotation = real_t(0.);
m_brake = real_t(0.);
@@ -172,6 +314,7 @@ void VehicleBody::_update_wheel_transform(VehicleWheel& wheel ,PhysicsDirectBody
//}
wheel.m_raycastInfo.m_hardPointWS = chassisTrans.xform( wheel.m_chassisConnectionPointCS );
+ //wheel.m_raycastInfo.m_hardPointWS+=s->get_linear_velocity()*s->get_step();
wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.get_basis().xform( wheel.m_wheelDirectionCS).normalized();
wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.get_basis().xform( wheel.m_wheelAxleCS ).normalized();
}
@@ -189,12 +332,16 @@ void VehicleBody::_update_wheel(int p_idx,PhysicsDirectBodyState *s) {
// up.normalize();
//rotate around steering over de wheelAxleWS
- real_t steering = wheel.m_steering;
+ real_t steering = wheel.steers?m_steeringValue:0.0;
+ //print_line(itos(p_idx)+": "+rtos(steering));
Matrix3 steeringMat(up,steering);
Matrix3 rotatingMat(right,-wheel.m_rotation);
+// if (p_idx==1)
+// print_line("steeringMat " +steeringMat);
+
Matrix3 basis2(
right[0],up[0],fwd[0],
right[1],up[1],fwd[1],
@@ -202,9 +349,11 @@ void VehicleBody::_update_wheel(int p_idx,PhysicsDirectBodyState *s) {
);
wheel.m_worldTransform.set_basis(steeringMat * rotatingMat * basis2);
+ //wheel.m_worldTransform.set_basis(basis2 * (steeringMat * rotatingMat));
wheel.m_worldTransform.set_origin(
wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength
);
+
}
@@ -221,9 +370,10 @@ real_t VehicleBody::_ray_cast(int p_idx,PhysicsDirectBodyState *s) {
real_t raylen = wheel.m_suspensionRestLength+wheel.m_wheelRadius;
Vector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
- const Vector3& source = wheel.m_raycastInfo.m_hardPointWS;
+ Vector3 source = wheel.m_raycastInfo.m_hardPointWS;
wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
const Vector3& target = wheel.m_raycastInfo.m_contactPointWS;
+ source-=wheel.m_wheelRadius * wheel.m_raycastInfo.m_wheelDirectionWS;
real_t param = real_t(0.);
@@ -552,9 +702,10 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
//const btTransform& wheelTrans = getWheelTransformWS( i );
- Matrix3 wheelBasis0 = wheelInfo.get_global_transform().basis;
+ Matrix3 wheelBasis0 = wheelInfo.m_worldTransform.basis;//get_global_transform().basis;
+
m_axle[i] = wheelBasis0.get_axis(Vector3::AXIS_X);
- m_axle[i] = wheelInfo.m_raycastInfo.m_wheelAxleWS;
+ //m_axle[i] = wheelInfo.m_raycastInfo.m_wheelAxleWS;
const Vector3& surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS;
real_t proj = m_axle[i].dot(surfNormalWS);
@@ -592,9 +743,9 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
if (wheelInfo.m_raycastInfo.m_isInContact)
{
- if (wheelInfo.m_engineForce != 0.f)
+ if (engine_force != 0.f)
{
- rollingFriction = wheelInfo.m_engineForce* s->get_step();
+ rollingFriction = engine_force* s->get_step();
} else
{
real_t defaultRollingFrictionImpulse = 0.f;
@@ -721,9 +872,11 @@ void VehicleBody::_direct_state_changed(Object *p_state) {
_update_wheel(i,s);
}
+
for(int i=0;i<wheels.size();i++) {
_ray_cast(i,s);
+ wheels[i]->set_transform(s->get_transform().inverse() * wheels[i]->m_worldTransform);
}
_update_suspension(s);
@@ -808,6 +961,35 @@ real_t VehicleBody::get_friction() const{
return friction;
}
+void VehicleBody::set_engine_force(float p_force) {
+
+ engine_force=p_force;
+}
+
+float VehicleBody::get_engine_force() const{
+
+ return engine_force;
+}
+
+void VehicleBody::set_brake(float p_brake){
+
+ brake=p_brake;
+}
+float VehicleBody::get_brake() const{
+
+ return brake;
+}
+
+void VehicleBody::set_steering(float p_steering){
+
+ m_steeringValue=p_steering;
+}
+float VehicleBody::get_steering() const{
+
+ return m_steeringValue;
+}
+
+
void VehicleBody::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_mass","mass"),&VehicleBody::set_mass);
@@ -816,8 +998,20 @@ void VehicleBody::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_friction","friction"),&VehicleBody::set_friction);
ObjectTypeDB::bind_method(_MD("get_friction"),&VehicleBody::get_friction);
+ ObjectTypeDB::bind_method(_MD("set_engine_force","engine_force"),&VehicleBody::set_engine_force);
+ ObjectTypeDB::bind_method(_MD("get_engine_force"),&VehicleBody::get_engine_force);
+
+ ObjectTypeDB::bind_method(_MD("set_brake","brake"),&VehicleBody::set_brake);
+ ObjectTypeDB::bind_method(_MD("get_brake"),&VehicleBody::get_brake);
+
+ ObjectTypeDB::bind_method(_MD("set_steering","steering"),&VehicleBody::set_steering);
+ ObjectTypeDB::bind_method(_MD("get_steering"),&VehicleBody::get_steering);
+
ObjectTypeDB::bind_method(_MD("_direct_state_changed"),&VehicleBody::_direct_state_changed);
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/engine_force",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_engine_force"),_SCS("get_engine_force"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/brake",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_brake"),_SCS("get_brake"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/steering",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_steering"),_SCS("get_steering"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/mass",PROPERTY_HINT_RANGE,"0.01,65536,0.01"),_SCS("set_mass"),_SCS("get_mass"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/friction",PROPERTY_HINT_RANGE,"0.01,1,0.01"),_SCS("set_friction"),_SCS("get_friction"));
@@ -833,8 +1027,11 @@ VehicleBody::VehicleBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
m_currentVehicleSpeedKmHour = real_t(0.);
m_steeringValue = real_t(0.);
+ engine_force=0;
+ brake=0;
+
+
- mass=1;
friction=1;
ccd=false;
@@ -842,5 +1039,6 @@ VehicleBody::VehicleBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
exclude.insert(get_rid());
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),this,"_direct_state_changed");
+ set_mass(40);
}
diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h
index 97137da699..285cca142d 100644
--- a/scene/3d/vehicle_body.h
+++ b/scene/3d/vehicle_body.h
@@ -14,6 +14,8 @@ friend class VehicleBody;
Transform m_worldTransform;
Transform local_xform;
+ bool engine_traction;
+ bool steers;
Vector3 m_chassisConnectionPointCS; //const
@@ -39,7 +41,7 @@ friend class VehicleBody;
real_t m_rotation;
real_t m_deltaRotation;
real_t m_rollInfluence;
- real_t m_engineForce;
+ //real_t m_engineForce;
real_t m_brake;
real_t m_clippedInvContactDotSuspension;
@@ -69,6 +71,35 @@ protected:
public:
+ void set_radius(float p_radius);
+ float get_radius() const;
+
+ void set_suspension_rest_length(float p_length);
+ float get_suspension_rest_length() const;
+
+ void set_suspension_travel(float p_length);
+ float get_suspension_travel() const;
+
+ void set_suspension_stiffness(float p_value);
+ float get_suspension_stiffness() const;
+
+ void set_suspension_max_force(float p_value);
+ float get_suspension_max_force() const;
+
+ void set_damping_compression(float p_value);
+ float get_damping_compression() const;
+
+ void set_damping_relaxation(float p_value);
+ float get_damping_relaxation() const;
+
+ void set_friction_slip(float p_value);
+ float get_friction_slip() const;
+
+ void set_use_as_traction(bool p_enable);
+ bool is_used_as_traction() const;
+
+ void set_use_as_steering(bool p_enabled);
+ bool is_used_as_steering() const;
VehicleWheel();
@@ -82,6 +113,9 @@ class VehicleBody : public PhysicsBody {
real_t mass;
real_t friction;
+ float engine_force;
+ float brake;
+
Vector3 linear_velocity;
Vector3 angular_velocity;
bool ccd;
@@ -135,6 +169,15 @@ public:
void set_friction(real_t p_friction);
real_t get_friction() const;
+ void set_engine_force(float p_engine_force);
+ float get_engine_force() const;
+
+ void set_brake(float p_force);
+ float get_brake() const;
+
+ void set_steering(float p_steering);
+ float get_steering() const;
+
VehicleBody();
};
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 3c95b102d7..2d6f3cd27a 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -113,7 +113,7 @@ void TabContainer::_input_event(const InputEvent& p_event) {
break;
}
- String s = c->has_meta("_tab_title")?String(XL_MESSAGE(String(c->get_meta("_tab_title")))):String(c->get_name());
+ String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
int tab_width=font->get_string_size(s).width;
if (c->has_meta("_tab_icon")) {
@@ -220,7 +220,7 @@ void TabContainer::_notification(int p_what) {
continue;
- String s = c->has_meta("_tab_title")?String(XL_MESSAGE(String(c->get_meta("_tab_title")))):String(c->get_name());
+ String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
w+=font->get_string_size(s).width;
if (c->has_meta("_tab_icon")) {
Ref<Texture> icon = c->get_meta("_tab_icon");
@@ -284,7 +284,7 @@ void TabContainer::_notification(int p_what) {
continue;
}
- String s = c->has_meta("_tab_title")?String(c->get_meta("_tab_title")):String(c->get_name());
+ String s = c->has_meta("_tab_name")?String(c->get_meta("_tab_name")):String(c->get_name());
int w=font->get_string_size(s).width;
Ref<Texture> icon;
if (c->has_meta("_tab_icon")) {
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index b7c857b9c7..ae7a4d59a7 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -278,7 +278,8 @@ void Tabs::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_tab_title","tab_idx"),&Tabs::get_tab_title);
ObjectTypeDB::bind_method(_MD("set_tab_icon","tab_idx","icon:Texture"),&Tabs::set_tab_icon);
ObjectTypeDB::bind_method(_MD("get_tab_icon:Texture","tab_idx"),&Tabs::get_tab_icon);
- ObjectTypeDB::bind_method(_MD("remove_tab","tab_idx","icon:Texture"),&Tabs::remove_tab);
+ ObjectTypeDB::bind_method(_MD("remove_tab","tab_idx"),&Tabs::remove_tab);
+ ObjectTypeDB::bind_method(_MD("add_tab","title","icon:Texture"),&Tabs::add_tab);
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index fb85f0c6b7..25f04379ef 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2787,7 +2787,7 @@ int Tree::get_item_offset(TreeItem *p_item) const {
ofs+=compute_item_height(it)+cache.vseparation;
- if (it->childs) {
+ if (it->childs && !it->collapsed) {
it=it->childs;
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index e3bb50a9af..9a1c070529 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -46,6 +46,7 @@ void VideoPlayer::_notification(int p_notification) {
if (paused)
return;
+ stream->update(get_scene()->get_idle_process_time());
while (stream->get_pending_frame_count()) {
Image img = stream->pop_frame();
@@ -104,10 +105,6 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stop();
- if (stream_rid.is_valid())
- AudioServer::get_singleton()->free(stream_rid);
- stream_rid=RID();
-
texture = Ref<ImageTexture>(memnew(ImageTexture));
stream=p_stream;
@@ -115,7 +112,6 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stream->set_loop(loops);
stream->set_paused(paused);
- stream_rid=AudioServer::get_singleton()->audio_stream_create(stream->get_audio_stream());
}
};
@@ -131,8 +127,6 @@ void VideoPlayer::play() {
if (stream.is_null())
return;
stream->play();
- AudioServer::get_singleton()->stream_set_active(stream_rid,true);
- AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
set_process(true);
};
@@ -143,7 +137,6 @@ void VideoPlayer::stop() {
if (stream.is_null())
return;
- AudioServer::get_singleton()->stream_set_active(stream_rid,false);
stream->stop();
set_process(false);
};
@@ -173,8 +166,6 @@ bool VideoPlayer::is_paused() const {
void VideoPlayer::set_volume(float p_vol) {
volume=p_vol;
- if (stream_rid.is_valid())
- AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
};
float VideoPlayer::get_volume() const {
@@ -213,6 +204,7 @@ float VideoPlayer::get_pos() const {
return stream->get_pos();
};
+
void VideoPlayer::set_autoplay(bool p_enable) {
autoplay=p_enable;
@@ -253,7 +245,7 @@ void VideoPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_expand"), &VideoPlayer::has_expand );
- ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"AudioStream"), _SCS("set_stream"), _SCS("get_stream") );
+ ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"VideoStream"), _SCS("set_stream"), _SCS("get_stream") );
// ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") );
ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") );
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 1926570885..bcdc50c880 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -481,8 +481,10 @@ bool SceneMainLoop::iteration(float p_time) {
_flush_transform_notifications();
MainLoop::iteration(p_time);
-
fixed_process_time=p_time;
+
+ emit_signal("fixed_frame");
+
_notify_group_pause("fixed_process",Node::NOTIFICATION_FIXED_PROCESS);
_flush_ugc();
_flush_transform_notifications();
@@ -507,6 +509,8 @@ bool SceneMainLoop::idle(float p_time){
idle_process_time=p_time;
+ emit_signal("idle_frame");
+
_flush_transform_notifications();
_notify_group_pause("idle_process",Node::NOTIFICATION_PROCESS);
@@ -1063,6 +1067,11 @@ SceneMainLoop::SceneMainLoop() {
ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree,this);
}
+ root->set_physics_object_picking(GLOBAL_DEF("physics/enable_object_picking",true));
+
+ ADD_SIGNAL( MethodInfo("idle_frame"));
+ ADD_SIGNAL( MethodInfo("fixed_frame"));
+
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index ea78ece9dc..92dcef803c 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -36,6 +36,7 @@
#include "scene/gui/control.h"
#include "scene/3d/camera.h"
#include "scene/3d/spatial_indexer.h"
+#include "scene/3d/collision_object.h"
@@ -94,6 +95,8 @@ void Viewport::_update_stretch_transform() {
if (size_override_stretch && size_override) {
+ print_line("sive override size "+size_override_size);
+ print_line("rect size "+rect.size);
stretch_transform=Matrix32();
Size2 scale = rect.size/(size_override_size+size_override_margin*2);
stretch_transform.scale(scale);
@@ -233,6 +236,40 @@ void Viewport::update_worlds() {
find_world()->_update(get_scene()->get_frame());
}
+
+void Viewport::_test_new_mouseover(ObjectID new_collider) {
+
+ if (new_collider!=physics_object_over) {
+
+ if (physics_object_over) {
+ Object *obj = ObjectDB::get_instance(physics_object_over);
+ if (obj) {
+ CollisionObject *co = obj->cast_to<CollisionObject>();
+ if (co) {
+ co->_mouse_exit();
+ }
+ }
+ }
+
+ if (new_collider) {
+ Object *obj = ObjectDB::get_instance(new_collider);
+ if (obj) {
+ CollisionObject *co = obj->cast_to<CollisionObject>();
+ if (co) {
+ co->_mouse_enter();
+
+ }
+ }
+
+ }
+
+ physics_object_over=new_collider;
+
+ }
+
+
+}
+
void Viewport::_notification(int p_what) {
@@ -308,6 +345,155 @@ void Viewport::_notification(int p_what) {
remove_from_group("_viewports");
} break;
+ case NOTIFICATION_FIXED_PROCESS: {
+
+ if (physics_object_picking) {
+
+ Vector2 last_pos(1e20,1e20);
+ CollisionObject *last_object;
+ ObjectID last_id=0;
+ PhysicsDirectSpaceState::RayResult result;
+
+ bool motion_tested=false;
+
+ while(physics_picking_events.size()) {
+
+ InputEvent ev = physics_picking_events.front()->get();
+ physics_picking_events.pop_front();
+
+ Vector2 pos;
+ switch(ev.type) {
+ case InputEvent::MOUSE_MOTION: {
+ pos.x=ev.mouse_motion.x;
+ pos.y=ev.mouse_motion.y;
+ motion_tested=true;
+ physics_last_mousepos=pos;
+ } break;
+ case InputEvent::MOUSE_BUTTON: {
+ pos.x=ev.mouse_button.x;
+ pos.y=ev.mouse_button.y;
+
+ } break;
+ case InputEvent::SCREEN_DRAG: {
+ pos.x=ev.screen_drag.x;
+ pos.y=ev.screen_drag.y;
+ } break;
+ case InputEvent::SCREEN_TOUCH: {
+ pos.x=ev.screen_touch.x;
+ pos.y=ev.screen_touch.y;
+ } break;
+
+ }
+
+ bool captured=false;
+
+ if (physics_object_capture!=0) {
+
+
+ Object *obj = ObjectDB::get_instance(physics_object_capture);
+ if (obj) {
+ CollisionObject *co = obj->cast_to<CollisionObject>();
+ if (co) {
+ co->_input_event(ev,Vector3(),Vector3(),0);
+ captured=true;
+ if (ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && !ev.mouse_button.pressed) {
+ physics_object_capture=0;
+ }
+
+ } else {
+ physics_object_capture=0;
+ }
+ } else {
+ physics_object_capture=0;
+ }
+ }
+
+
+ if (captured) {
+ //none
+ } else if (pos==last_pos) {
+
+ if (last_id) {
+ if (ObjectDB::get_instance(last_id)) {
+ //good, exists
+ last_object->_input_event(ev,result.position,result.normal,result.shape);
+ if (last_object->get_capture_input_on_drag() && ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && ev.mouse_button.pressed) {
+ physics_object_capture=last_id;
+ }
+
+
+ }
+ }
+ } else {
+
+
+
+
+ if (camera) {
+
+ Vector3 from = camera->project_ray_origin(pos);
+ Vector3 dir = camera->project_ray_normal(pos);
+
+ PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space());
+ if (space) {
+
+ bool col = space->intersect_ray(from,from+dir*10000,result,Set<RID>(),0xFFFFFFFF,0xFFFFFFFF);
+ ObjectID new_collider=0;
+ if (col) {
+ if (result.collider) {
+ CollisionObject *co = result.collider->cast_to<CollisionObject>();
+ if (co) {
+ co->_input_event(ev,result.position,result.normal,result.shape);
+ last_object=co;
+ last_id=result.collider_id;
+ new_collider=last_id;
+ if (co->get_capture_input_on_drag() && ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && ev.mouse_button.pressed) {
+ physics_object_capture=last_id;
+ }
+
+ }
+ }
+ }
+
+ if (ev.type==InputEvent::MOUSE_MOTION) {
+ _test_new_mouseover(new_collider);
+ }
+ }
+
+ last_pos=pos;
+ }
+ }
+ }
+
+ if (!motion_tested && camera && physics_last_mousepos!=Vector2(1e20,1e20)) {
+
+ //test anyway for mouseenter/exit because objects might move
+ Vector3 from = camera->project_ray_origin(physics_last_mousepos);
+ Vector3 dir = camera->project_ray_normal(physics_last_mousepos);
+
+ PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space());
+ if (space) {
+
+ bool col = space->intersect_ray(from,from+dir*10000,result,Set<RID>(),0xFFFFFFFF,0xFFFFFFFF);
+ ObjectID new_collider=0;
+ if (col) {
+ if (result.collider) {
+ CollisionObject *co = result.collider->cast_to<CollisionObject>();
+ if (co) {
+ new_collider=result.collider_id;
+
+ }
+ }
+ }
+
+ _test_new_mouseover(new_collider);
+
+ }
+
+ }
+ }
+
+ } break;
}
}
@@ -888,7 +1074,8 @@ void Viewport::_vp_input(const InputEvent& p_ev) {
void Viewport::_vp_unhandled_input(const InputEvent& p_ev) {
- if (render_target)
+
+ if (render_target && to_screen_rect==Rect2())
return; //if render target, can't get input events
//this one handles system input, p_ev are in system coordinates
@@ -917,6 +1104,15 @@ void Viewport::unhandled_input(const InputEvent& p_event) {
get_scene()->_call_input_pause(unhandled_key_input_group,"_unhandled_key_input",p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
}
+
+
+ if (physics_object_picking && !get_scene()->input_handled) {
+
+ if (p_event.type==InputEvent::MOUSE_BUTTON || p_event.type==InputEvent::MOUSE_MOTION || p_event.type==InputEvent::SCREEN_DRAG || p_event.type==InputEvent::SCREEN_TOUCH) {
+ physics_picking_events.push_back(p_event);
+ }
+ }
+
}
void Viewport::set_use_own_world(bool p_world) {
@@ -973,6 +1169,22 @@ Rect2 Viewport::get_render_target_to_screen_rect() const{
return to_screen_rect;
}
+void Viewport::set_physics_object_picking(bool p_enable) {
+
+ physics_object_picking=p_enable;
+ set_fixed_process(physics_object_picking);
+ if (!physics_object_picking)
+ physics_picking_events.clear();
+
+
+}
+
+bool Viewport::get_physics_object_picking() {
+
+
+ return physics_object_picking;
+}
+
void Viewport::_bind_methods() {
@@ -1028,6 +1240,9 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_render_target_texture:RenderTargetTexture"), &Viewport::get_render_target_texture);
+ ObjectTypeDB::bind_method(_MD("set_physics_object_picking","enable"), &Viewport::set_physics_object_picking);
+ ObjectTypeDB::bind_method(_MD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
+
ObjectTypeDB::bind_method(_MD("get_viewport"), &Viewport::get_viewport);
ObjectTypeDB::bind_method(_MD("input","local_event"), &Viewport::input);
ObjectTypeDB::bind_method(_MD("unhandled_input","local_event"), &Viewport::unhandled_input);
@@ -1037,6 +1252,7 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_use_own_world","enable"), &Viewport::set_use_own_world);
ObjectTypeDB::bind_method(_MD("is_using_own_world"), &Viewport::is_using_own_world);
+ ObjectTypeDB::bind_method(_MD("get_camera:Camera"), &Viewport::get_camera);
ObjectTypeDB::bind_method(_MD("set_as_audio_listener","enable"), &Viewport::set_as_audio_listener);
ObjectTypeDB::bind_method(_MD("is_audio_listener","enable"), &Viewport::is_audio_listener);
@@ -1058,6 +1274,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") );
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"physics/object_picking"), _SCS("set_physics_object_picking"), _SCS("get_physics_object_picking") );
ADD_SIGNAL(MethodInfo("size_changed"));
@@ -1093,6 +1310,11 @@ Viewport::Viewport() {
render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
+ physics_object_picking=false;
+ physics_object_capture=0;
+ physics_object_over=0;
+ physics_last_mousepos=Vector2(1e20,1e20);
+
String id=itos(get_instance_ID());
input_group = "_vp_input"+id;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 6feb89b084..5d68438f0d 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -116,6 +116,13 @@ friend class RenderTargetTexture;
bool render_target_filter;
bool render_target_gen_mipmaps;
+ bool physics_object_picking;
+ List<InputEvent> physics_picking_events;
+ ObjectID physics_object_capture;
+ ObjectID physics_object_over;
+ Vector2 physics_last_mousepos;
+ void _test_new_mouseover(ObjectID new_collider);
+
void _update_rect();
void _parent_resized();
@@ -234,6 +241,9 @@ public:
void set_render_target_to_screen_rect(const Rect2& p_rect);
Rect2 get_render_target_to_screen_rect() const;
+ void set_physics_object_picking(bool p_enable);
+ bool get_physics_object_picking();
+
Viewport();
~Viewport();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index f7d6a246e6..08e6ff2e54 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -199,7 +199,7 @@
#include "scene/3d/proximity_group.h"
#include "scene/3d/navigation_mesh.h"
#include "scene/3d/navigation.h"
-
+#include "scene/3d/collision_polygon.h"
#endif
#include "scene/scene_binds.h"
@@ -401,6 +401,7 @@ void register_scene_types() {
ObjectTypeDB::register_virtual_type<CollisionObject>();
ObjectTypeDB::register_type<StaticBody>();
ObjectTypeDB::register_type<RigidBody>();
+ ObjectTypeDB::register_type<KinematicBody>();
ObjectTypeDB::register_type<CarBody>();
ObjectTypeDB::register_type<CarWheel>();
ObjectTypeDB::register_type<VehicleBody>();
@@ -408,6 +409,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<Area>();
ObjectTypeDB::register_type<ProximityGroup>();
ObjectTypeDB::register_type<CollisionShape>();
+ ObjectTypeDB::register_type<CollisionPolygon>();
ObjectTypeDB::register_type<RayCast>();
ObjectTypeDB::register_virtual_type<EditableShape>();
ObjectTypeDB::register_type<EditableSphere>();
@@ -443,9 +445,17 @@ void register_scene_types() {
//ObjectTypeDB::register_type<BodyVolumeBox>();
//ObjectTypeDB::register_type<BodyVolumeCylinder>();
//ObjectTypeDB::register_type<BodyVolumeCapsule>();
- //ObjectTypeDB::register_virtual_type<PhysicsJoint>();
//ObjectTypeDB::register_type<PhysicsJointPin>();
+
+ ObjectTypeDB::register_virtual_type<Joint>();
+ ObjectTypeDB::register_type<PinJoint>();
+ ObjectTypeDB::register_type<HingeJoint>();
+ ObjectTypeDB::register_type<SliderJoint>();
+ ObjectTypeDB::register_type<ConeTwistJoint>();
+ ObjectTypeDB::register_type<Generic6DOFJoint>();
+
+
ObjectTypeDB::register_type<StreamPlayer>();
ObjectTypeDB::register_type<EventPlayer>();
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 32bc8670f0..eafacce159 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -33,19 +33,37 @@
-class VideoStream : public AudioStreamResampled {
+class VideoStream : public Resource {
- OBJ_TYPE(VideoStream,AudioStreamResampled);
+ OBJ_TYPE(VideoStream,Resource);
protected:
static void _bind_methods();
public:
+ virtual void stop()=0;
+ virtual void play()=0;
+
+ virtual bool is_playing() const=0;
+
+ virtual void set_paused(bool p_paused)=0;
+ virtual bool is_paused(bool p_paused) const=0;
+
+ virtual void set_loop(bool p_enable)=0;
+ virtual bool has_loop() const=0;
+
+ virtual float get_length() const=0;
+
+ virtual float get_pos() const=0;
+ virtual void seek_pos(float p_time)=0;
+
virtual int get_pending_frame_count() const=0;
virtual Image pop_frame()=0;
virtual Image peek_frame() const=0;
+ virtual void update(float p_time)=0;
+
VideoStream();
};
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index 0576d5a5b1..1d99eb6d1f 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -144,5 +144,7 @@ SceneStringNames::SceneStringNames() {
baked_light_changed = StaticCString::create("baked_light_changed");
_baked_light_changed = StaticCString::create("_baked_light_changed");
+ _mouse_enter=StaticCString::create("_mouse_enter");
+ _mouse_exit=StaticCString::create("_mouse_exit");
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index d4de0555ed..dd4f8789c2 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -152,6 +152,10 @@ public:
StringName baked_light_changed;
StringName _baked_light_changed;
+ StringName _mouse_enter;
+ StringName _mouse_exit;
+
+
};