summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/canvas_item.cpp9
-rw-r--r--scene/2d/canvas_item.h3
-rw-r--r--scene/2d/node_2d.cpp28
-rw-r--r--scene/2d/node_2d.h4
-rw-r--r--scene/2d/physics_body_2d.cpp28
-rw-r--r--scene/2d/physics_body_2d.h6
-rw-r--r--scene/2d/ray_cast_2d.cpp17
-rw-r--r--scene/2d/ray_cast_2d.h4
-rw-r--r--scene/2d/screen_button.cpp4
-rw-r--r--scene/2d/tile_map.cpp21
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/3d/baked_light.cpp7
-rw-r--r--scene/3d/baked_light.h15
-rw-r--r--scene/3d/immediate_geometry.cpp102
-rw-r--r--scene/3d/immediate_geometry.h41
-rw-r--r--scene/3d/light.cpp5
-rw-r--r--scene/3d/light.h3
-rw-r--r--scene/3d/mesh_instance.cpp35
-rw-r--r--scene/3d/mesh_instance.h7
-rw-r--r--scene/3d/physics_body.cpp16
-rw-r--r--scene/3d/physics_body.h15
-rw-r--r--scene/3d/sprite_3d.cpp772
-rw-r--r--scene/3d/sprite_3d.h191
-rw-r--r--scene/3d/visual_instance.cpp4
-rw-r--r--scene/3d/visual_instance.h1
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/audio/sample_player.cpp2
-rw-r--r--scene/gui/line_edit.cpp5
-rw-r--r--scene/gui/popup.cpp16
-rw-r--r--scene/gui/popup.h4
-rw-r--r--scene/gui/rich_text_label.cpp4
-rw-r--r--scene/gui/text_edit.cpp199
-rw-r--r--scene/gui/text_edit.h15
-rw-r--r--scene/main/viewport.cpp17
-rw-r--r--scene/main/viewport.h4
-rw-r--r--scene/register_scene_types.cpp8
-rw-r--r--scene/resources/environment.cpp18
-rw-r--r--scene/resources/environment.h11
-rw-r--r--scene/resources/material.cpp13
-rw-r--r--scene/resources/material.h3
-rw-r--r--scene/resources/mesh.cpp57
-rw-r--r--scene/resources/mesh.h4
-rw-r--r--scene/resources/surface_tool.cpp441
-rw-r--r--scene/resources/surface_tool.h12
-rw-r--r--scene/resources/texture.cpp55
-rw-r--r--scene/resources/texture.h3
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h4
48 files changed, 2049 insertions, 192 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index b9cddfa572..d66f100b3f 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -447,7 +447,7 @@ float CanvasItem::get_self_opacity() const {
void CanvasItem::set_blend_mode(BlendMode p_blend_mode) {
- ERR_FAIL_INDEX(p_blend_mode,4);
+ ERR_FAIL_INDEX(p_blend_mode,5);
blend_mode=p_blend_mode;
VisualServer::get_singleton()->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(blend_mode));
@@ -772,8 +772,8 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("draw_texture_rect_region","texture:Texture","rect","src_rect","modulate"),&CanvasItem::draw_texture_rect_region,DEFVAL(Color(1,1,1)));
ObjectTypeDB::bind_method(_MD("draw_style_box","style_box:StyleBox","rect"),&CanvasItem::draw_style_box);
ObjectTypeDB::bind_method(_MD("draw_primitive","points","colors","uvs","texture:Texture","width"),&CanvasItem::draw_primitive,DEFVAL(Array()),DEFVAL(Ref<Texture>()),DEFVAL(1.0));
- ObjectTypeDB::bind_method(_MD("draw_polygon","points","colors","uvs","texture:Texture"),&CanvasItem::draw_primitive,DEFVAL(Array()),DEFVAL(Ref<Texture>()));
- ObjectTypeDB::bind_method(_MD("draw_colored_polygon","points","color","uvs","texture:Texture"),&CanvasItem::draw_primitive,DEFVAL(Array()),DEFVAL(Ref<Texture>()));
+ ObjectTypeDB::bind_method(_MD("draw_polygon","points","colors","uvs","texture:Texture"),&CanvasItem::draw_polygon,DEFVAL(Array()),DEFVAL(Ref<Texture>()));
+ ObjectTypeDB::bind_method(_MD("draw_colored_polygon","points","color","uvs","texture:Texture"),&CanvasItem::draw_colored_polygon,DEFVAL(Array()),DEFVAL(Ref<Texture>()));
ObjectTypeDB::bind_method(_MD("draw_string","font:Font","pos","text","modulate","clip_w"),&CanvasItem::draw_string,DEFVAL(Color(1,1,1)),DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("draw_char","font:Font","pos","char","next","modulate"),&CanvasItem::draw_char,DEFVAL(Color(1,1,1)));
@@ -794,7 +794,7 @@ void CanvasItem::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
- ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
+ ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
//exporting these two things doesn't really make much sense i think
//ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") );
//ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled"));
@@ -810,6 +810,7 @@ void CanvasItem::_bind_methods() {
BIND_CONSTANT( BLEND_MODE_ADD );
BIND_CONSTANT( BLEND_MODE_SUB );
BIND_CONSTANT( BLEND_MODE_MUL );
+ BIND_CONSTANT( BLEND_MODE_PREMULT_ALPHA );
BIND_CONSTANT( NOTIFICATION_DRAW);
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 1c104c5fc2..604eef0527 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -49,7 +49,8 @@ public:
BLEND_MODE_MIX, //default
BLEND_MODE_ADD,
BLEND_MODE_SUB,
- BLEND_MODE_MUL
+ BLEND_MODE_MUL,
+ BLEND_MODE_PREMULT_ALPHA
};
private:
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index a2bee43e58..85adfbbbde 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -224,6 +224,30 @@ Rect2 Node2D::get_item_rect() const {
return Rect2(Point2(-32,-32),Size2(64,64));
}
+void Node2D::rotate(float p_degrees) {
+
+ set_rot( get_rot() + p_degrees);
+}
+
+void Node2D::move_x(float p_delta,bool p_scaled){
+
+ Matrix32 t = get_transform();
+ Vector2 m = t[0];
+ if (!p_scaled)
+ m.normalize();
+ set_pos(t[2]+m*p_delta);
+}
+
+void Node2D::move_y(float p_delta,bool p_scaled){
+
+ Matrix32 t = get_transform();
+ Vector2 m = t[1];
+ if (!p_scaled)
+ m.normalize();
+ set_pos(t[2]+m*p_delta);
+}
+
+
Point2 Node2D::get_global_pos() const {
return get_global_transform().get_origin();
@@ -268,6 +292,10 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_rot"),&Node2D::get_rot);
ObjectTypeDB::bind_method(_MD("get_scale"),&Node2D::get_scale);
+ ObjectTypeDB::bind_method(_MD("rotate","degrees"),&Node2D::rotate);
+ ObjectTypeDB::bind_method(_MD("move_local_x","delta","scaled"),&Node2D::move_x,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("move_local_y","delta","scaled"),&Node2D::move_y,DEFVAL(false));
+
ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos);
ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform);
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index 8da441dc63..8e1f22c235 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -70,6 +70,10 @@ public:
void set_rot(float p_angle);
void set_scale(const Size2& p_scale);
+ void rotate(float p_degrees);
+ void move_x(float p_delta,bool p_scaled=false);
+ void move_y(float p_delta,bool p_scaled=false);
+
Point2 get_pos() const;
float get_rot() const;
Size2 get_scale() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index a1e7195b0a..ecd147afde 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -43,9 +43,27 @@ void PhysicsBody2D::_notification(int p_what) {
*/
}
-PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
+void PhysicsBody2D::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+}
+
+void PhysicsBody2D::set_layer_mask(uint32_t p_mask) {
+
+ mask=p_mask;
+ Physics2DServer::get_singleton()->body_set_layer_mask(get_rid(),p_mask);
+}
+
+uint32_t PhysicsBody2D::get_layer_mask() const {
+ return mask;
+}
+
+PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
+ mask=1;
}
@@ -789,7 +807,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
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),Vector2(),margin,sr,max_shapes,res_shapes,exclude,0,mask))
+ if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask))
collided=true;
}
@@ -834,7 +852,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
float lsafe,lunsafe;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,0,mask);
+ 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);
//print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
if (!valid) {
safe=0;
@@ -865,7 +883,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
Matrix32 ugt = get_global_transform();
ugt.elements[2]+=p_motion*unsafe;
Physics2DDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,0,mask);
+ bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask);
if (!c2) {
//should not happen, but floating point precision is so weird..
colliding=false;
@@ -927,7 +945,7 @@ bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) {
for(int i=0;i<get_shape_count();i++) {
- bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,0,mask);
+ bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,get_layer_mask(),mask);
if (col)
return false;
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index e7b65b1ef3..1319d2e4f0 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -38,12 +38,18 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
+ uint32_t mask;
protected:
void _notification(int p_what);
PhysicsBody2D(Physics2DServer::BodyMode p_mode);
+
+ static void _bind_methods();
public:
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
PhysicsBody2D();
};
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 540c825485..8479338521 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -43,6 +43,16 @@ Vector2 RayCast2D::get_cast_to() const{
return cast_to;
}
+void RayCast2D::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+}
+
+uint32_t RayCast2D::get_layer_mask() const {
+
+ return layer_mask;
+}
+
bool RayCast2D::is_colliding() const{
return collided;
@@ -152,7 +162,7 @@ void RayCast2D::_notification(int p_what) {
Physics2DDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude)) {
+ if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) {
collided=true;
against=rr.collider_id;
@@ -228,8 +238,12 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast2D::clear_exceptions);
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
}
RayCast2D::RayCast2D() {
@@ -238,5 +252,6 @@ RayCast2D::RayCast2D() {
against=0;
collided=false;
against_shape=0;
+ layer_mask=1;
cast_to=Vector2(0,50);
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 32b95fbefe..b27fc4bf3d 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -43,6 +43,7 @@ class RayCast2D : public Node2D {
Vector2 collision_point;
Vector2 collision_normal;
Set<RID> exclude;
+ uint32_t layer_mask;
Vector2 cast_to;
@@ -58,6 +59,9 @@ public:
void set_cast_to(const Vector2& p_point);
Vector2 get_cast_to() const;
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;
diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp
index 32a5323419..9d0c9f3d1a 100644
--- a/scene/2d/screen_button.cpp
+++ b/scene/2d/screen_button.cpp
@@ -242,8 +242,8 @@ void TouchScreenButton::_input(const InputEvent& p_event) {
touched=true;
}
} else {
-
- touched=Rect2(Point2(),texture->get_size()).has_point(coord);
+ if (!texture.is_null())
+ touched=Rect2(Point2(),texture->get_size()).has_point(coord);
}
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c8711f10ac..6fe8b8c4c2 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -315,6 +315,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const
VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() );
VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform );
q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC);
+ Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer);
if (is_inside_scene()) {
xform = get_global_transform() * xform;
RID space = get_world_2d()->get_space();
@@ -545,6 +546,22 @@ Rect2 TileMap::get_item_rect() const {
return rect_cache;
}
+void TileMap::set_collision_layer_mask(uint32_t p_layer) {
+
+ collision_layer=p_layer;
+ for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
+
+ Quadrant &q=E->get();
+ Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer);
+ }
+}
+
+uint32_t TileMap::get_collision_layer_mask() const {
+
+ return collision_layer;
+}
+
+
void TileMap::_bind_methods() {
@@ -564,6 +581,8 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_center_y","enable"),&TileMap::set_center_y);
ObjectTypeDB::bind_method(_MD("get_center_y"),&TileMap::get_center_y);
+ ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask);
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
@@ -583,6 +602,7 @@ void TileMap::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size"));
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset"));
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision_layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask"));
ADD_SIGNAL(MethodInfo("settings_changed"));
@@ -599,6 +619,7 @@ TileMap::TileMap() {
cell_size=64;
center_x=false;
center_y=false;
+ collision_layer=1;
fp_adjust=0.01;
fp_adjust=0.01;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index a2414382c6..9265a7b55e 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -98,6 +98,7 @@ class TileMap : public Node2D {
Rect2 rect_cache;
bool rect_cache_dirty;
float fp_adjust;
+ uint32_t collision_layer;
Map<PosKey,Quadrant>::Element *_create_quadrant(const PosKey& p_qk);
@@ -145,6 +146,9 @@ public:
Rect2 get_item_rect() const;
+ void set_collision_layer_mask(uint32_t p_layer);
+ uint32_t get_collision_layer_mask() const;
+
void clear();
TileMap();
diff --git a/scene/3d/baked_light.cpp b/scene/3d/baked_light.cpp
new file mode 100644
index 0000000000..55832b7c18
--- /dev/null
+++ b/scene/3d/baked_light.cpp
@@ -0,0 +1,7 @@
+#include "baked_light.h"
+#include "mesh_instance.h"
+
+BakedLight::BakedLight() {
+
+
+}
diff --git a/scene/3d/baked_light.h b/scene/3d/baked_light.h
new file mode 100644
index 0000000000..a6f997afe9
--- /dev/null
+++ b/scene/3d/baked_light.h
@@ -0,0 +1,15 @@
+#ifndef BAKED_LIGHT_H
+#define BAKED_LIGHT_H
+
+#include "scene/3d/spatial.h"
+class BakedLightBaker;
+
+
+class BakedLight : public Spatial {
+ OBJ_TYPE(BakedLight,Spatial);
+
+public:
+ BakedLight();
+};
+
+#endif // BAKED_LIGHT_H
diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp
new file mode 100644
index 0000000000..1459f2c362
--- /dev/null
+++ b/scene/3d/immediate_geometry.cpp
@@ -0,0 +1,102 @@
+#include "immediate_geometry.h"
+
+
+void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture) {
+
+ VS::get_singleton()->immediate_begin(im,(VS::PrimitiveType)p_primitive,p_texture.is_valid()?p_texture->get_rid():RID());
+ if (p_texture.is_valid())
+ cached_textures.push_back(p_texture);
+
+}
+
+void ImmediateGeometry::set_normal(const Vector3& p_normal){
+
+ VS::get_singleton()->immediate_normal(im,p_normal);
+}
+
+void ImmediateGeometry::set_tangent(const Plane& p_tangent){
+
+ VS::get_singleton()->immediate_tangent(im,p_tangent);
+
+}
+
+void ImmediateGeometry::set_color(const Color& p_color){
+
+ VS::get_singleton()->immediate_color(im,p_color);
+
+}
+
+void ImmediateGeometry::set_uv(const Vector2& p_uv){
+
+ VS::get_singleton()->immediate_uv(im,p_uv);
+
+}
+
+void ImmediateGeometry::set_uv2(const Vector2& p_uv2){
+
+ VS::get_singleton()->immediate_uv2(im,p_uv2);
+
+}
+
+void ImmediateGeometry::add_vertex(const Vector3& p_vertex){
+
+ VS::get_singleton()->immediate_vertex(im,p_vertex);
+ if (empty) {
+ aabb.pos=p_vertex;
+ aabb.size=Vector3();
+ } else {
+ aabb.expand_to(p_vertex);
+ }
+}
+
+void ImmediateGeometry::end(){
+
+ VS::get_singleton()->immediate_end(im);
+
+}
+
+void ImmediateGeometry::clear(){
+
+ VS::get_singleton()->immediate_clear(im);
+ empty=true;
+ cached_textures.clear();
+
+}
+
+AABB ImmediateGeometry::get_aabb() const {
+
+ return aabb;
+}
+DVector<Face3> ImmediateGeometry::get_faces(uint32_t p_usage_flags) const {
+
+ return DVector<Face3>();
+}
+
+void ImmediateGeometry::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("begin","primitive","texture:Texture"),&ImmediateGeometry::begin);
+ ObjectTypeDB::bind_method(_MD("set_normal","normal"),&ImmediateGeometry::set_normal);
+ ObjectTypeDB::bind_method(_MD("set_tangent","tangent"),&ImmediateGeometry::set_tangent);
+ ObjectTypeDB::bind_method(_MD("set_color","color"),&ImmediateGeometry::set_color);
+ ObjectTypeDB::bind_method(_MD("set_uv","uv"),&ImmediateGeometry::set_uv);
+ ObjectTypeDB::bind_method(_MD("set_uv2","uv"),&ImmediateGeometry::set_uv2);
+ ObjectTypeDB::bind_method(_MD("add_vertex","color"),&ImmediateGeometry::add_vertex);
+ ObjectTypeDB::bind_method(_MD("end"),&ImmediateGeometry::end);
+ ObjectTypeDB::bind_method(_MD("clear"),&ImmediateGeometry::clear);
+
+}
+
+ImmediateGeometry::ImmediateGeometry() {
+
+ im = VisualServer::get_singleton()->immediate_create();
+ set_base(im);
+ empty=true;
+
+}
+
+
+ImmediateGeometry::~ImmediateGeometry() {
+
+ VisualServer::get_singleton()->free(im);
+
+}
diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h
new file mode 100644
index 0000000000..2db81134c6
--- /dev/null
+++ b/scene/3d/immediate_geometry.h
@@ -0,0 +1,41 @@
+#ifndef IMMEDIATE_GEOMETRY_H
+#define IMMEDIATE_GEOMETRY_H
+
+#include "scene/3d/visual_instance.h"
+#include "scene/resources/mesh.h"
+
+class ImmediateGeometry : public GeometryInstance {
+
+ OBJ_TYPE(ImmediateGeometry,GeometryInstance);
+
+
+ RID im;
+ List<Ref<Texture> > cached_textures;
+ bool empty;
+ AABB aabb;
+protected:
+
+ static void _bind_methods();
+public:
+
+
+ void begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture);
+ void set_normal(const Vector3& p_normal);
+ void set_tangent(const Plane& p_tangent);
+ void set_color(const Color& p_color);
+ void set_uv(const Vector2& tex_uv);
+ void set_uv2(const Vector2& tex_uv);
+
+ void add_vertex(const Vector3& p_vertex);
+
+ void end();
+ void clear();
+
+ virtual AABB get_aabb() const;
+ virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
+
+ ImmediateGeometry();
+ ~ImmediateGeometry();
+};
+
+#endif // IMMEDIATE_GEOMETRY_H
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 94c56850ef..b4b7b400c6 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -540,14 +540,15 @@ void DirectionalLight::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param);
ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param);
- ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
BIND_CONSTANT( SHADOW_ORTHOGONAL );
BIND_CONSTANT( SHADOW_PERSPECTIVE );
- BIND_CONSTANT( SHADOW_PARALLEL_SPLIT );
+ BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
+ BIND_CONSTANT( SHADOW_PARALLEL_4_SPLITS );
BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE );
BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT );
BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE );
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 03bf336303..dea7dbee6c 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -138,7 +138,8 @@ public:
enum ShadowMode {
SHADOW_ORTHOGONAL,
SHADOW_PERSPECTIVE,
- SHADOW_PARALLEL_SPLIT
+ SHADOW_PARALLEL_2_SPLITS,
+ SHADOW_PARALLEL_4_SPLITS
};
enum ShadowParam {
SHADOW_PARAM_MAX_DISTANCE,
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index 6387f5fdbc..40981d468e 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -113,6 +113,27 @@ Ref<Mesh> MeshInstance::get_mesh() const {
return mesh;
}
+void MeshInstance::_resolve_skeleton_path(){
+
+ if (skeleton_path.is_empty())
+ return;
+
+ Skeleton *skeleton=get_node(skeleton_path)?get_node(skeleton_path)->cast_to<Skeleton>():NULL;
+ if (skeleton)
+ VisualServer::get_singleton()->instance_attach_skeleton( get_instance(), skeleton->get_skeleton() );
+}
+
+void MeshInstance::set_skeleton_path(const NodePath &p_skeleton) {
+
+ skeleton_path = p_skeleton;
+ if (!is_inside_scene())
+ return;
+ _resolve_skeleton_path();
+}
+
+NodePath MeshInstance::get_skeleton_path() {
+ return skeleton_path;
+}
AABB MeshInstance::get_aabb() const {
@@ -192,22 +213,32 @@ void MeshInstance::create_convex_collision() {
}
+void MeshInstance::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_SCENE) {
+ _resolve_skeleton_path();
+ }
+}
+
+
void MeshInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_mesh","mesh:Mesh"),&MeshInstance::set_mesh);
ObjectTypeDB::bind_method(_MD("get_mesh:Mesh"),&MeshInstance::get_mesh);
+ ObjectTypeDB::bind_method(_MD("set_skeleton_path","skeleton_path:NodePath"),&MeshInstance::set_skeleton_path);
+ ObjectTypeDB::bind_method(_MD("get_skeleton_path:NodePath"),&MeshInstance::get_skeleton_path);
ObjectTypeDB::bind_method(_MD("get_aabb"),&MeshInstance::get_aabb);
ObjectTypeDB::bind_method(_MD("create_trimesh_collision"),&MeshInstance::create_trimesh_collision);
ObjectTypeDB::set_method_flags("MeshInstance","create_trimesh_collision",METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
ObjectTypeDB::bind_method(_MD("create_convex_collision"),&MeshInstance::create_convex_collision);
ObjectTypeDB::set_method_flags("MeshInstance","create_convex_collision",METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "mesh/mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh" ), _SCS("set_mesh"), _SCS("get_mesh"));
-
-
+ ADD_PROPERTY( PropertyInfo (Variant::NODE_PATH, "mesh/skeleton"), _SCS("set_skeleton_path"), _SCS("get_skeleton_path"));
}
MeshInstance::MeshInstance()
{
+ skeleton_path=NodePath("..");
}
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
index 0e07109502..1b97564b4e 100644
--- a/scene/3d/mesh_instance.h
+++ b/scene/3d/mesh_instance.h
@@ -40,6 +40,7 @@ class MeshInstance : public GeometryInstance {
OBJ_TYPE( MeshInstance, GeometryInstance );
Ref<Mesh> mesh;
+ NodePath skeleton_path;
struct MorphTrack {
@@ -50,6 +51,7 @@ class MeshInstance : public GeometryInstance {
Map<StringName,MorphTrack> morph_tracks;
+ void _resolve_skeleton_path();
protected:
@@ -57,12 +59,15 @@ protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
+ void _notification(int p_what);
static void _bind_methods();
public:
void set_mesh(const Ref<Mesh>& p_mesh);
Ref<Mesh> get_mesh() const;
+
+ void set_skeleton_path(const NodePath& p_skeleton);
+ NodePath get_skeleton_path();
Node* create_trimesh_collision_node();
void create_trimesh_collision();
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 0733a9196e..2a1a5972a9 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -632,6 +632,16 @@ bool RigidBody::is_contact_monitor_enabled() const {
return contact_monitor!=NULL;
}
+void RigidBody::set_axis_lock(AxisLock p_lock) {
+
+ axis_lock=p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(),PhysicsServer::BodyAxisLock(axis_lock));
+}
+
+RigidBody::AxisLock RigidBody::get_axis_lock() const {
+
+ return axis_lock;
+}
void RigidBody::_bind_methods() {
@@ -682,6 +692,9 @@ void RigidBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_body_enter_scene"),&RigidBody::_body_enter_scene);
ObjectTypeDB::bind_method(_MD("_body_exit_scene"),&RigidBody::_body_exit_scene);
+ ObjectTypeDB::bind_method(_MD("set_axis_lock","axis_lock"),&RigidBody::set_axis_lock);
+ ObjectTypeDB::bind_method(_MD("get_axis_lock"),&RigidBody::get_axis_lock);
+
BIND_VMETHOD(MethodInfo("_integrate_forces",PropertyInfo(Variant::OBJECT,"state:PhysicsDirectBodyState")));
ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Rigid,Static,Character,Kinematic"),_SCS("set_mode"),_SCS("get_mode"));
@@ -695,6 +708,7 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"contact_monitor"),_SCS("set_contact_monitor"),_SCS("is_contact_monitor_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"active"),_SCS("set_active"),_SCS("is_active"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"axis_lock",PROPERTY_HINT_ENUM,"Disabled,Lock X,Lock Y,Lock Z"),_SCS("set_axis_lock"),_SCS("get_axis_lock"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity"));
@@ -727,6 +741,8 @@ RigidBody::RigidBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
contact_monitor=NULL;
can_sleep=true;
+ axis_lock = AXIS_LOCK_DISABLED;
+
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),this,"_direct_state_changed");
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index a5faa9857b..6695ee719a 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -94,6 +94,14 @@ public:
MODE_CHARACTER,
MODE_KINEMATIC,
};
+
+ enum AxisLock {
+ AXIS_LOCK_DISABLED,
+ AXIS_LOCK_X,
+ AXIS_LOCK_Y,
+ AXIS_LOCK_Z,
+ };
+
private:
bool can_sleep;
@@ -109,6 +117,8 @@ private:
bool active;
bool ccd;
+ AxisLock axis_lock;
+
int max_contacts_reported;
@@ -208,6 +218,10 @@ public:
void set_use_continuous_collision_detection(bool p_enable);
bool is_using_continuous_collision_detection() const;
+ void set_axis_lock(AxisLock p_lock);
+ AxisLock get_axis_lock() const;
+
+
void apply_impulse(const Vector3& p_pos, const Vector3& p_impulse);
RigidBody();
@@ -216,4 +230,5 @@ public:
};
VARIANT_ENUM_CAST(RigidBody::Mode);
+VARIANT_ENUM_CAST(RigidBody::AxisLock);
#endif // PHYSICS_BODY__H
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
new file mode 100644
index 0000000000..21fdb9abd3
--- /dev/null
+++ b/scene/3d/sprite_3d.cpp
@@ -0,0 +1,772 @@
+#include "sprite_3d.h"
+#include "scene/scene_string_names.h"
+#include "core_string_names.h"
+
+
+Color SpriteBase3D::_get_color_accum() {
+
+ if (!color_dirty)
+ return color_accum;
+
+ if (parent_sprite)
+ color_accum=parent_sprite->_get_color_accum();
+ else
+ color_accum=Color(1,1,1,1);
+
+ color_accum.r*=modulate.r;
+ color_accum.g*=modulate.g;
+ color_accum.b*=modulate.b;
+ color_accum.a*=modulate.a;
+ color_dirty=false;
+ return color_accum;
+}
+
+void SpriteBase3D::_propagate_color_changed() {
+
+ if (color_dirty)
+ return;
+
+ color_dirty=true;
+ _queue_update();
+
+ for (List<SpriteBase3D*>::Element *E=children.front();E;E=E->next()) {
+
+ E->get()->_propagate_color_changed();
+ }
+}
+
+void SpriteBase3D::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_SCENE) {
+
+ if (!pending_update)
+ _im_update();
+
+ Node *parent=get_parent();
+ if (parent) {
+
+ parent_sprite=parent->cast_to<SpriteBase3D>();
+ if (parent_sprite) {
+ pI=parent_sprite->children.push_back(this);
+ }
+ }
+ }
+
+ if (p_what==NOTIFICATION_EXIT_SCENE) {
+
+
+ if (parent_sprite) {
+
+ parent_sprite->children.erase(pI);
+ pI=NULL;
+ parent_sprite=NULL;
+ }
+ }
+
+}
+
+
+void SpriteBase3D::set_centered(bool p_center) {
+
+ centered=p_center;
+ _queue_update();
+
+}
+
+bool SpriteBase3D::is_centered() const {
+
+ return centered;
+}
+
+void SpriteBase3D::set_offset(const Point2& p_offset) {
+
+ offset=p_offset;
+ _queue_update();
+
+}
+Point2 SpriteBase3D::get_offset() const {
+
+ return offset;
+}
+
+void SpriteBase3D::set_flip_h(bool p_flip) {
+
+ hflip=p_flip;
+ _queue_update();
+}
+bool SpriteBase3D::is_flipped_h() const {
+
+ return hflip;
+}
+
+void SpriteBase3D::set_flip_v(bool p_flip) {
+
+ vflip=p_flip;
+ _queue_update();
+}
+bool SpriteBase3D::is_flipped_v() const {
+
+ return vflip;
+}
+
+
+
+void SpriteBase3D::set_modulate(const Color& p_color) {
+
+ modulate=p_color;
+ _propagate_color_changed();
+ _queue_update();
+}
+
+Color SpriteBase3D::get_modulate() const{
+
+ return modulate;
+}
+
+
+void SpriteBase3D::set_pixel_size(float p_amount) {
+
+ pixel_size=p_amount;
+ _queue_update();
+}
+float SpriteBase3D::get_pixel_size() const {
+
+ return pixel_size;
+}
+
+void SpriteBase3D::set_opacity(float p_amount) {
+
+ opacity=p_amount;
+ _queue_update();
+}
+float SpriteBase3D::get_opacity() const {
+
+ return opacity;
+}
+
+
+void SpriteBase3D::set_axis(Vector3::Axis p_axis) {
+
+ axis=p_axis;
+ _queue_update();
+}
+Vector3::Axis SpriteBase3D::get_axis() const {
+
+ return axis;
+}
+
+
+
+void SpriteBase3D::_im_update() {
+
+
+ _draw();
+
+
+ pending_update=false;
+
+ //texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
+
+}
+
+void SpriteBase3D::_queue_update(){
+
+ if (pending_update)
+ return;
+
+ pending_update=true;
+ call_deferred(SceneStringNames::get_singleton()->_im_update);
+}
+
+
+AABB SpriteBase3D::get_aabb() const {
+
+ return aabb;
+}
+DVector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const {
+
+ return DVector<Face3>();
+
+}
+
+void SpriteBase3D::set_draw_flag(DrawFlags p_flag,bool p_enable) {
+
+ ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ flags[p_flag]=p_enable;
+ _queue_update();
+}
+
+bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const{
+ ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+ return flags[p_flag];
+}
+
+void SpriteBase3D::set_alpha_cut_mode(AlphaCutMode p_mode){
+
+ ERR_FAIL_INDEX(p_mode,3);
+ alpha_cut=p_mode;
+ _queue_update();
+
+}
+
+SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const{
+
+ return alpha_cut;
+}
+
+
+void SpriteBase3D::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method(_MD("set_centered","centered"),&SpriteBase3D::set_centered);
+ ObjectTypeDB::bind_method(_MD("is_centered"),&SpriteBase3D::is_centered);
+
+ ObjectTypeDB::bind_method(_MD("set_offset","offset"),&SpriteBase3D::set_offset);
+ ObjectTypeDB::bind_method(_MD("get_offset"),&SpriteBase3D::get_offset);
+
+ ObjectTypeDB::bind_method(_MD("set_flip_h","flip_h"),&SpriteBase3D::set_flip_h);
+ ObjectTypeDB::bind_method(_MD("is_flipped_h"),&SpriteBase3D::is_flipped_h);
+
+ ObjectTypeDB::bind_method(_MD("set_flip_v","flip_v"),&SpriteBase3D::set_flip_v);
+ ObjectTypeDB::bind_method(_MD("is_flipped_v"),&SpriteBase3D::is_flipped_v);
+
+
+ ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&SpriteBase3D::set_modulate);
+ ObjectTypeDB::bind_method(_MD("get_modulate"),&SpriteBase3D::get_modulate);
+
+ ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&SpriteBase3D::set_opacity);
+ ObjectTypeDB::bind_method(_MD("get_opacity"),&SpriteBase3D::get_opacity);
+
+ ObjectTypeDB::bind_method(_MD("set_pixel_size","pixel_size"),&SpriteBase3D::set_pixel_size);
+ ObjectTypeDB::bind_method(_MD("get_pixel_size"),&SpriteBase3D::get_pixel_size);
+
+ ObjectTypeDB::bind_method(_MD("set_axis","axis"),&SpriteBase3D::set_axis);
+ ObjectTypeDB::bind_method(_MD("get_axis"),&SpriteBase3D::get_axis);
+
+ ObjectTypeDB::bind_method(_MD("set_draw_flag","flag","enabled"),&SpriteBase3D::set_draw_flag);
+ ObjectTypeDB::bind_method(_MD("get_draw_flag","flag"),&SpriteBase3D::get_draw_flag);
+
+ ObjectTypeDB::bind_method(_MD("set_alpha_cut_mode","mode"),&SpriteBase3D::set_alpha_cut_mode);
+ ObjectTypeDB::bind_method(_MD("get_alpha_cut_mode"),&SpriteBase3D::get_alpha_cut_mode);
+
+ ObjectTypeDB::bind_method(_MD("get_item_rect"),&SpriteBase3D::get_item_rect);
+
+ ObjectTypeDB::bind_method(_MD("_queue_update"),&SpriteBase3D::_queue_update);
+ ObjectTypeDB::bind_method(_MD("_im_update"),&SpriteBase3D::_im_update);
+
+
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
+ ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
+ ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
+ ADD_PROPERTY( PropertyInfo( Variant::REAL, "opacity",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity"));
+ ADD_PROPERTY( PropertyInfo( Variant::REAL, "pixel_size",PROPERTY_HINT_RANGE,"0.0001,128,0.0001"), _SCS("set_pixel_size"),_SCS("get_pixel_size"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "axis",PROPERTY_HINT_ENUM,"X-Axis,Y-Axis,Z-Axis"), _SCS("set_axis"),_SCS("get_axis"));
+ ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "flags/transparent"), _SCS("set_draw_flag"),_SCS("get_draw_flag"),FLAG_TRANSPARENT);
+ ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "flags/shaded"), _SCS("set_draw_flag"),_SCS("get_draw_flag"),FLAG_SHADED);
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "flags/alpha_cut",PROPERTY_HINT_ENUM,"Disabled,Discard,Opaque Pre-Pass"), _SCS("set_alpha_cut_mode"),_SCS("get_alpha_cut_mode"));
+
+
+ BIND_CONSTANT( FLAG_TRANSPARENT );
+ BIND_CONSTANT( FLAG_SHADED );
+ BIND_CONSTANT( FLAG_MAX );
+
+ BIND_CONSTANT( ALPHA_CUT_DISABLED );
+ BIND_CONSTANT( ALPHA_CUT_DISCARD );
+ BIND_CONSTANT( ALPHA_CUT_OPAQUE_PREPASS );
+}
+
+
+
+
+SpriteBase3D::SpriteBase3D() {
+
+ color_dirty=true;
+ centered=true;
+ hflip=false;
+ vflip=false;
+ parent_sprite=NULL;
+ pI=NULL;
+
+ for(int i=0;i<4;i++)
+ flags[i]=i==FLAG_TRANSPARENT;
+
+ axis=Vector3::AXIS_Z;
+ pixel_size=0.01;
+ modulate=Color(1,1,1,1);
+ pending_update=false;
+ opacity=1.0;
+ immediate = VisualServer::get_singleton()->immediate_create();
+ set_base(immediate);
+}
+
+
+SpriteBase3D::~SpriteBase3D() {
+
+ VisualServer::get_singleton()->free(immediate);
+}
+
+
+///////////////////////////////////////////
+
+
+void Sprite3D::_draw() {
+
+ RID immediate = get_immediate();
+
+ VS::get_singleton()->immediate_clear(immediate);
+ if (!texture.is_valid())
+ return; //no texuture no life
+ Vector2 tsize = texture->get_size();
+ if (tsize.x==0 || tsize.y==0)
+ return;
+
+ Size2i s;
+ Rect2i src_rect;
+
+ if (region) {
+
+ s=region_rect.size;
+ src_rect=region_rect;
+ } else {
+ s = texture->get_size();
+ s=s/Size2i(hframes,vframes);
+
+ src_rect.size=s;
+ src_rect.pos.x+=(frame%hframes)*s.x;
+ src_rect.pos.y+=(frame/hframes)*s.y;
+
+ }
+
+ Point2i ofs=get_offset();
+ if (is_centered())
+ ofs-=s/2;
+
+ Rect2i dst_rect(ofs,s);
+
+
+ Rect2 final_rect;
+ Rect2 final_src_rect;
+ if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
+ return;
+
+
+ if (final_rect.size.x==0 || final_rect.size.y==0)
+ return;
+
+ Color color=_get_color_accum();
+ color.a*=get_opacity();
+
+ float pixel_size=get_pixel_size();
+
+ Vector2 vertices[4]={
+
+ (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
+ (final_rect.pos+final_rect.size) * pixel_size,
+ (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
+ final_rect.pos * pixel_size,
+
+
+ };
+ Vector2 uvs[4]={
+ final_src_rect.pos / tsize,
+ (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
+ (final_src_rect.pos+final_src_rect.size) / tsize,
+ (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
+ };
+
+ if (is_flipped_h()) {
+ SWAP(uvs[0],uvs[1]);
+ SWAP(uvs[2],uvs[3]);
+ }
+ if (is_flipped_v()) {
+
+ SWAP(uvs[0],uvs[3]);
+ SWAP(uvs[1],uvs[2]);
+ }
+
+
+ Vector3 normal;
+ int axis = get_axis();
+ normal[axis]=1.0;
+
+ RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
+ VS::get_singleton()->immediate_set_material(immediate,mat);
+
+ VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());
+
+ int x_axis = ((axis + 1) % 3);
+ int y_axis = ((axis + 2) % 3);
+
+ AABB aabb;
+
+ for(int i=0;i<4;i++) {
+ VS::get_singleton()->immediate_normal(immediate,normal);
+ VS::get_singleton()->immediate_color(immediate,color);
+ VS::get_singleton()->immediate_uv(immediate,uvs[i]);
+
+ Vector3 vtx;
+ vtx[x_axis]=vertices[i][x_axis];
+ vtx[y_axis]=vertices[i][y_axis];
+ VS::get_singleton()->immediate_vertex(immediate,vtx);
+ if (i==0) {
+ aabb.pos=vtx;
+ aabb.size=Vector3();
+ } else {
+ aabb.expand_to(vtx);
+ }
+ }
+ set_aabb(aabb);
+ VS::get_singleton()->immediate_end(immediate);
+
+
+}
+
+void Sprite3D::set_texture(const Ref<Texture>& p_texture) {
+
+ if (p_texture==texture)
+ return;
+ if (texture.is_valid()) {
+ texture->disconnect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_queue_update);
+ }
+ texture=p_texture;
+ if (texture.is_valid()) {
+ texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites
+ texture->connect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_queue_update);
+ }
+ _queue_update();
+
+}
+
+Ref<Texture> Sprite3D::get_texture() const {
+
+ return texture;
+}
+
+void Sprite3D::set_region(bool p_region) {
+
+ if (p_region==region)
+ return;
+
+ region=p_region;
+ _queue_update();
+}
+
+bool Sprite3D::is_region() const{
+
+ return region;
+}
+
+void Sprite3D::set_region_rect(const Rect2& p_region_rect) {
+
+ bool changed=region_rect!=p_region_rect;
+ region_rect=p_region_rect;
+ if (region && changed) {
+ _queue_update();
+ }
+}
+
+Rect2 Sprite3D::get_region_rect() const {
+
+ return region_rect;
+}
+
+void Sprite3D::set_frame(int p_frame) {
+
+ ERR_FAIL_INDEX(p_frame,vframes*hframes);
+
+ if (frame != p_frame)
+
+ frame=p_frame;
+}
+
+int Sprite3D::get_frame() const {
+
+ return frame;
+}
+
+void Sprite3D::set_vframes(int p_amount) {
+
+ ERR_FAIL_COND(p_amount<1);
+ vframes=p_amount;
+ _queue_update();
+ _change_notify("frame");
+}
+int Sprite3D::get_vframes() const {
+
+ return vframes;
+}
+
+void Sprite3D::set_hframes(int p_amount) {
+
+ ERR_FAIL_COND(p_amount<1);
+ hframes=p_amount;
+ _queue_update();
+ _change_notify("frame");
+}
+int Sprite3D::get_hframes() const {
+
+ return hframes;
+}
+
+Rect2 Sprite3D::get_item_rect() const {
+
+ if (texture.is_null())
+ return Rect2(0,0,1,1);
+ //if (texture.is_null())
+ // return CanvasItem::get_item_rect();
+
+ Size2i s;
+
+ if (region) {
+
+ s=region_rect.size;
+ } else {
+ s = texture->get_size();
+ s=s/Point2(hframes,vframes);
+ }
+
+ Point2i ofs=get_offset();
+ if (is_centered())
+ ofs-=s/2;
+
+ if (s==Size2(0,0))
+ s=Size2(1,1);
+
+ return Rect2(ofs,s);
+}
+
+void Sprite3D::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_texture","texture:Texture"),&Sprite3D::set_texture);
+ ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&Sprite3D::get_texture);
+
+ ObjectTypeDB::bind_method(_MD("set_region","enabled"),&Sprite3D::set_region);
+ ObjectTypeDB::bind_method(_MD("is_region"),&Sprite3D::is_region);
+
+ ObjectTypeDB::bind_method(_MD("set_region_rect","rect"),&Sprite3D::set_region_rect);
+ ObjectTypeDB::bind_method(_MD("get_region_rect"),&Sprite3D::get_region_rect);
+
+ ObjectTypeDB::bind_method(_MD("set_frame","frame"),&Sprite3D::set_frame);
+ ObjectTypeDB::bind_method(_MD("get_frame"),&Sprite3D::get_frame);
+
+ ObjectTypeDB::bind_method(_MD("set_vframes","vframes"),&Sprite3D::set_vframes);
+ ObjectTypeDB::bind_method(_MD("get_vframes"),&Sprite3D::get_vframes);
+
+ ObjectTypeDB::bind_method(_MD("set_hframes","hframes"),&Sprite3D::set_hframes);
+ ObjectTypeDB::bind_method(_MD("get_hframes"),&Sprite3D::get_hframes);
+
+ ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame"));
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region"));
+ ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect"));
+
+}
+
+Sprite3D::Sprite3D() {
+
+
+ region=false;
+ frame=0;
+ vframes=1;
+ hframes=1;
+
+}
+
+////////////////////////////////////////
+
+
+void AnimatedSprite3D::_draw() {
+
+ RID immediate = get_immediate();
+ VS::get_singleton()->immediate_clear(immediate);
+
+ if (!frames.is_valid() || !frames->get_frame_count() || frame<0 || frame>=frames->get_frame_count()) {
+ return;
+ }
+
+ Ref<Texture> texture = frames->get_frame(frame);
+ if (!texture.is_valid())
+ return; //no texuture no life
+ Vector2 tsize = texture->get_size();
+ if (tsize.x==0 || tsize.y==0)
+ return;
+
+ Size2i s=tsize;
+ Rect2i src_rect;
+
+ src_rect.size=s;
+
+ Point2i ofs=get_offset();
+ if (is_centered())
+ ofs-=s/2;
+
+ Rect2i dst_rect(ofs,s);
+
+
+ Rect2 final_rect;
+ Rect2 final_src_rect;
+ if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
+ return;
+
+
+ if (final_rect.size.x==0 || final_rect.size.y==0)
+ return;
+
+ Color color=_get_color_accum();
+ color.a*=get_opacity();
+
+ float pixel_size=get_pixel_size();
+
+ Vector2 vertices[4]={
+
+ (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
+ (final_rect.pos+final_rect.size) * pixel_size,
+ (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
+ final_rect.pos * pixel_size,
+
+
+ };
+ Vector2 uvs[4]={
+ final_src_rect.pos / tsize,
+ (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
+ (final_src_rect.pos+final_src_rect.size) / tsize,
+ (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
+ };
+
+ if (is_flipped_h()) {
+ SWAP(uvs[0],uvs[1]);
+ SWAP(uvs[2],uvs[3]);
+ }
+ if (is_flipped_v()) {
+
+ SWAP(uvs[0],uvs[3]);
+ SWAP(uvs[1],uvs[2]);
+ }
+
+
+ Vector3 normal;
+ int axis = get_axis();
+ normal[axis]=1.0;
+
+ RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
+ VS::get_singleton()->immediate_set_material(immediate,mat);
+
+ VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());
+
+ int x_axis = ((axis + 1) % 3);
+ int y_axis = ((axis + 2) % 3);
+
+ AABB aabb;
+
+ for(int i=0;i<4;i++) {
+ VS::get_singleton()->immediate_normal(immediate,normal);
+ VS::get_singleton()->immediate_color(immediate,color);
+ VS::get_singleton()->immediate_uv(immediate,uvs[i]);
+
+ Vector3 vtx;
+ vtx[x_axis]=vertices[i][x_axis];
+ vtx[y_axis]=vertices[i][y_axis];
+ VS::get_singleton()->immediate_vertex(immediate,vtx);
+ if (i==0) {
+ aabb.pos=vtx;
+ aabb.size=Vector3();
+ } else {
+ aabb.expand_to(vtx);
+ }
+ }
+ set_aabb(aabb);
+ VS::get_singleton()->immediate_end(immediate);
+
+}
+
+void AnimatedSprite3D::_bind_methods(){
+
+ ObjectTypeDB::bind_method(_MD("set_sprite_frames","sprite_frames:SpriteFrames"),&AnimatedSprite3D::set_sprite_frames);
+ ObjectTypeDB::bind_method(_MD("get_sprite_frames:Texture"),&AnimatedSprite3D::get_sprite_frames);
+ ObjectTypeDB::bind_method(_MD("set_frame","frame"),&AnimatedSprite3D::set_frame);
+ ObjectTypeDB::bind_method(_MD("get_frame"),&AnimatedSprite3D::get_frame);
+
+ ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame"));
+
+}
+
+
+
+
+void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames>& p_sprite_frames) {
+
+
+ if (frames==p_sprite_frames)
+ return;
+
+ if (frames.is_valid())
+ frames->disconnect("changed",this,"_queue_update");
+ frames=p_sprite_frames;
+ if (frames.is_valid())
+ frames->connect("changed",this,"_queue_update");
+
+ if (!frames.is_valid() || frame >=frames->get_frame_count()) {
+ frame=0;
+
+ }
+ _queue_update();
+
+}
+
+Ref<SpriteFrames> AnimatedSprite3D::get_sprite_frames() const{
+
+ return frames;
+}
+
+void AnimatedSprite3D::set_frame(int p_frame){
+
+ if (frames.is_null())
+ return;
+
+ ERR_FAIL_INDEX(p_frame,frames->get_frame_count());
+
+ if (frame==p_frame)
+ return;
+
+ frame=p_frame;
+ _queue_update();
+
+}
+int AnimatedSprite3D::get_frame() const{
+
+ return frame;
+}
+
+Rect2 AnimatedSprite3D::get_item_rect() const {
+
+ if (!frames.is_valid() || !frames->get_frame_count() || frame<0 || frame>=frames->get_frame_count()) {
+ return Rect2(0,0,1,1);
+ }
+
+ Ref<Texture> t = frames->get_frame(frame);
+ if (t.is_null())
+ return Rect2(0,0,1,1);
+ Size2i s = t->get_size();
+
+ Point2i ofs=get_offset();
+ if (is_centered())
+ ofs-=s/2;
+
+ if (s==Size2(0,0))
+ s=Size2(1,1);
+
+ return Rect2(ofs,s);
+}
+
+
+
+AnimatedSprite3D::AnimatedSprite3D() {
+
+ frame=0;
+}
+
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
new file mode 100644
index 0000000000..1330cd1c30
--- /dev/null
+++ b/scene/3d/sprite_3d.h
@@ -0,0 +1,191 @@
+#ifndef SPRITE_3D_H
+#define SPRITE_3D_H
+
+#include "scene/3d/visual_instance.h"
+#include "scene/2d/animated_sprite.h"
+
+
+class SpriteBase3D : public VisualInstance {
+
+ OBJ_TYPE(SpriteBase3D,VisualInstance);
+public:
+
+ enum DrawFlags {
+ FLAG_TRANSPARENT,
+ FLAG_SHADED,
+ FLAG_MAX
+
+ };
+
+ enum AlphaCutMode {
+ ALPHA_CUT_DISABLED,
+ ALPHA_CUT_DISCARD,
+ ALPHA_CUT_OPAQUE_PREPASS
+ };
+
+private:
+
+
+ bool color_dirty;
+ Color color_accum;
+
+ SpriteBase3D *parent_sprite;
+ List<SpriteBase3D*> children;
+ List<SpriteBase3D*>::Element *pI;
+
+ bool centered;
+ Point2 offset;
+
+ bool hflip;
+ bool vflip;
+
+
+ Color modulate;
+ float opacity;
+
+ Vector3::Axis axis;
+ float pixel_size;
+ AABB aabb;
+
+ RID immediate;
+
+ bool flags[FLAG_MAX];
+ AlphaCutMode alpha_cut;
+ bool pending_update;
+ void _im_update();
+
+
+ void _propagate_color_changed();
+
+protected:
+
+ Color _get_color_accum();
+ void _notification(int p_what);
+ static void _bind_methods();
+ virtual void _draw()=0;
+ _FORCE_INLINE_ void set_aabb(const AABB& p_aabb) { aabb=p_aabb; }
+ _FORCE_INLINE_ RID& get_immediate() { return immediate; }
+ void _queue_update();
+public:
+
+ void set_centered(bool p_center);
+ bool is_centered() const;
+
+ void set_offset(const Point2& p_offset);
+ Point2 get_offset() const;
+
+ void set_flip_h(bool p_flip);
+ bool is_flipped_h() const;
+
+ void set_flip_v(bool p_flip);
+ bool is_flipped_v() const;
+
+ void set_region(bool p_region);
+ bool is_region() const;
+
+ void set_region_rect(const Rect2& p_region_rect);
+ Rect2 get_region_rect() const;
+
+ void set_modulate(const Color& p_color);
+ Color get_modulate() const;
+
+ void set_opacity(float p_amount);
+ float get_opacity() const;
+
+ void set_pixel_size(float p_amount);
+ float get_pixel_size() const;
+
+ void set_axis(Vector3::Axis p_amount);
+ Vector3::Axis get_axis() const;
+
+ void set_draw_flag(DrawFlags p_flag,bool p_enable);
+ bool get_draw_flag(DrawFlags p_flag) const;
+
+ void set_alpha_cut_mode(AlphaCutMode p_mode);
+ AlphaCutMode get_alpha_cut_mode() const;
+
+ virtual Rect2 get_item_rect() const=0;
+
+ virtual AABB get_aabb() const;
+ virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
+
+ SpriteBase3D();
+ ~SpriteBase3D();
+};
+
+
+class Sprite3D : public SpriteBase3D {
+
+ OBJ_TYPE(Sprite3D,SpriteBase3D);
+ Ref<Texture> texture;
+
+
+ bool region;
+ Rect2 region_rect;
+
+ int frame;
+
+ int vframes;
+ int hframes;
+protected:
+ virtual void _draw();
+ static void _bind_methods();
+public:
+
+
+
+ void set_texture(const Ref<Texture>& p_texture);
+ Ref<Texture> get_texture() const;
+
+ void set_region(bool p_region);
+ bool is_region() const;
+
+ void set_region_rect(const Rect2& p_region_rect);
+ Rect2 get_region_rect() const;
+
+ void set_frame(int p_frame);
+ int get_frame() const;
+
+ void set_vframes(int p_amount);
+ int get_vframes() const;
+
+ void set_hframes(int p_amount);
+ int get_hframes() const;
+
+ virtual Rect2 get_item_rect() const;
+
+ Sprite3D();
+// ~Sprite3D();
+};
+
+class AnimatedSprite3D : public SpriteBase3D {
+
+ OBJ_TYPE(AnimatedSprite3D,SpriteBase3D);
+ Ref<SpriteFrames> frames;
+
+
+ int frame;
+
+protected:
+ virtual void _draw();
+ static void _bind_methods();
+public:
+
+
+
+ void set_sprite_frames(const Ref<SpriteFrames>& p_sprite_frames);
+ Ref<SpriteFrames> get_sprite_frames() const;
+
+ void set_frame(int p_frame);
+ int get_frame() const;
+
+
+ virtual Rect2 get_item_rect() const;
+
+ AnimatedSprite3D();
+// ~AnimatedSprite3D();
+};
+
+VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags);
+VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode);
+#endif // SPRITE_3D_H
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 9419996187..96f16ab8c8 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -65,10 +65,12 @@ void VisualInstance::_notification(int p_what) {
VisualServer::get_singleton()->instance_set_room(instance,room->get_instance());
}
- // CHECK SKELETON
+ // CHECK SKELETON => moving skeleton attaching logic to MeshInstance
+ /*
Skeleton *skeleton=get_parent()?get_parent()->cast_to<Skeleton>():NULL;
if (skeleton)
VisualServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() );
+ */
VisualServer::get_singleton()->instance_set_scenario( instance, get_world()->get_scenario() );
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 4e652912c6..afb9ed70f8 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -91,6 +91,7 @@ public:
FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE,
FLAG_VISIBLE_IN_ALL_ROOMS=VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
+ FLAG_USE_BAKED_LIGHT_VOLUME=VS::INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME,
FLAG_MAX=VS::INSTANCE_FLAG_MAX,
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c659447c23..15d3dccb71 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -907,8 +907,8 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
}
}
- c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0;
c.current.from=&animation_set[name];
+ c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0;
c.current.speed_scale=p_custom_scale;
c.assigned=p_name;
diff --git a/scene/audio/sample_player.cpp b/scene/audio/sample_player.cpp
index be53b8243e..90994f01b4 100644
--- a/scene/audio/sample_player.cpp
+++ b/scene/audio/sample_player.cpp
@@ -52,7 +52,7 @@ bool SamplePlayer::_set(const StringName& p_name, const Variant& p_value) {
set_voice_count(p_value);
else if (name.begins_with("default/")) {
- String what=name.right(7);
+ String what=name.right(8);
if (what=="volume_db")
set_default_volume_db(p_value);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 6c9db7484b..e822cfef13 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -323,9 +323,12 @@ bool LineEdit::can_drop_data(const Point2& p_point,const Variant& p_data) const{
void LineEdit::drop_data(const Point2& p_point,const Variant& p_data){
if (p_data.get_type()==Variant::STRING) {
-
set_cursor_at_pixel_pos(p_point.x);
+ int selected = selection.end - selection.begin;
+ text.erase(selection.begin, selected);
append_at_cursor(p_data);
+ selection.begin = cursor_pos-selected;
+ selection.end = cursor_pos;
}
}
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 0a5b72d2ed..65ad02723c 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -38,7 +38,13 @@ void Popup::_input_event(InputEvent p_event) {
void Popup::_notification(int p_what) {
-
+ if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
+ if (popped_up && !is_visible()) {
+ popped_up=false;
+ notification(NOTIFICATION_POPUP_HIDE);
+ emit_signal("popup_hide");
+ }
+ }
}
void Popup::_fix_size() {
@@ -101,6 +107,7 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
popup_centered( total_minsize );
+ popped_up=true;
}
@@ -127,6 +134,7 @@ void Popup::popup_centered(const Size2& p_size) {
_post_popup();
notification(NOTIFICATION_POST_POPUP);
+ popped_up=true;
}
void Popup::popup_centered_ratio(float p_screen_ratio) {
@@ -153,6 +161,7 @@ void Popup::popup_centered_ratio(float p_screen_ratio) {
_post_popup();
notification(NOTIFICATION_POST_POPUP);
+ popped_up=true;
}
@@ -171,6 +180,7 @@ void Popup::popup() {
_post_popup();
notification(NOTIFICATION_POST_POPUP);
+ popped_up=true;
}
void Popup::set_exclusive(bool p_exclusive) {
@@ -193,8 +203,11 @@ void Popup::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_exclusive","enable"),&Popup::set_exclusive);
ObjectTypeDB::bind_method(_MD("is_exclusive"),&Popup::is_exclusive);
ADD_SIGNAL( MethodInfo("about_to_show") );
+ ADD_SIGNAL( MethodInfo("popup_hide") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "popup/exclusive"), _SCS("set_exclusive"),_SCS("is_exclusive") );
BIND_CONSTANT(NOTIFICATION_POST_POPUP);
+ BIND_CONSTANT(NOTIFICATION_POPUP_HIDE);
+
}
@@ -202,6 +215,7 @@ Popup::Popup() {
set_as_toplevel(true);
exclusive=false;
+ popped_up=false;
hide();
}
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 3744ff283f..072b66c2c7 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -39,6 +39,7 @@ class Popup : public Control {
OBJ_TYPE( Popup, Control );
bool exclusive;
+ bool popped_up;
protected:
@@ -51,7 +52,8 @@ protected:
public:
enum {
- NOTIFICATION_POST_POPUP=80
+ NOTIFICATION_POST_POPUP=80,
+ NOTIFICATION_POPUP_HIDE=81
};
void set_exclusive(bool p_exclusive);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 5ac278a38e..241d66fce4 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1512,6 +1512,10 @@ void RichTextLabel::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled);
ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled);
+ ObjectTypeDB::bind_method(_MD("parse_bbcode", "bbcode"),&RichTextLabel::parse_bbcode);
+ ObjectTypeDB::bind_method(_MD("append_bbcode", "bbcode"),&RichTextLabel::append_bbcode);
+
+
ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta")));
BIND_CONSTANT( ALIGN_LEFT );
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a6207c5611..3566c1bfc4 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -46,7 +46,6 @@
#define TAB_PIXELS
-
static bool _is_text_char(CharType c) {
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
@@ -57,6 +56,42 @@ static bool _is_symbol(CharType c) {
return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t');
}
+static bool _is_pair_right_symbol(CharType c) {
+ return
+ c == '"' ||
+ c == '\'' ||
+ c == ')' ||
+ c == ']' ||
+ c == '}';
+}
+
+static bool _is_pair_left_symbol(CharType c) {
+ return
+ c == '"' ||
+ c == '\'' ||
+ c == '(' ||
+ c == '[' ||
+ c == '{';
+}
+
+static bool _is_pair_symbol(CharType c) {
+ return _is_pair_left_symbol(c) || _is_pair_right_symbol(c);
+}
+
+static CharType _get_right_pair_symbol(CharType c) {
+ if(c == '"')
+ return '"';
+ if(c == '\'')
+ return '\'';
+ if(c == '(')
+ return ')';
+ if(c == '[')
+ return ']';
+ if(c == '{')
+ return '}';
+ return 0;
+}
+
void TextEdit::Text::set_font(const Ref<Font>& p_font) {
font=p_font;
@@ -301,7 +336,7 @@ void TextEdit::_update_scrollbars() {
v_scroll->set_val(cursor.line_ofs);
} else {
-
+ cursor.line_ofs = 0;
v_scroll->hide();
}
@@ -707,6 +742,93 @@ void TextEdit::_notification(int p_what) {
}
}
+void TextEdit::_consume_pair_symbol(CharType ch) {
+
+ int cursor_position_to_move = cursor_get_column() + 1;
+
+ CharType ch_single[2] = {ch, 0};
+ CharType ch_single_pair[2] = {_get_right_pair_symbol(ch), 0};
+ CharType ch_pair[3] = {ch, _get_right_pair_symbol(ch), 0};
+
+ if(is_selection_active()) {
+
+ int new_column,new_line;
+
+ _begin_compex_operation();
+ _insert_text(get_selection_from_line(), get_selection_from_column(),
+ ch_single,
+ &new_line, &new_column);
+
+ int to_col_offset = 0;
+ if(get_selection_from_line() == get_selection_to_line())
+ to_col_offset = 1;
+
+ _insert_text(get_selection_to_line(),
+ get_selection_to_column() + to_col_offset,
+ ch_single_pair,
+ &new_line,&new_column);
+ _end_compex_operation();
+
+ cursor_set_line(get_selection_to_line());
+ cursor_set_column(get_selection_to_column() + to_col_offset);
+
+ deselect();
+ update();
+ return;
+ }
+
+ if( (ch == '\'' || ch == '"') &&
+ cursor_get_column() > 0 &&
+ _is_text_char(text[cursor.line][cursor_get_column() - 1])
+ ) {
+ insert_text_at_cursor(ch_single);
+ cursor_set_column(cursor_position_to_move);
+ return;
+ }
+
+ if(cursor_get_column() < text[cursor.line].length()) {
+ if(_is_text_char(text[cursor.line][cursor_get_column()])) {
+ insert_text_at_cursor(ch_single);
+ cursor_set_column(cursor_position_to_move);
+ return;
+ }
+ if( _is_pair_right_symbol(ch) &&
+ text[cursor.line][cursor_get_column()] == ch
+ ) {
+ cursor_set_column(cursor_position_to_move);
+ return;
+ }
+ }
+
+
+ insert_text_at_cursor(ch_pair);
+ cursor_set_column(cursor_position_to_move);
+ return;
+
+}
+
+void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) {
+
+ bool remove_right_symbol = false;
+
+ if(cursor.column < text[cursor.line].length() && cursor.column > 0) {
+
+ CharType left_char = text[cursor.line][cursor.column - 1];
+ CharType right_char = text[cursor.line][cursor.column];
+
+ if(right_char == _get_right_pair_symbol(left_char)) {
+ remove_right_symbol = true;
+ }
+
+ }
+ if(remove_right_symbol) {
+ _remove_text(prev_line,prev_column,cursor.line,cursor.column + 1);
+ } else {
+ _remove_text(prev_line,prev_column,cursor.line,cursor.column);
+ }
+
+}
+
void TextEdit::backspace_at_cursor() {
if (cursor.column==0 && cursor.line==0)
@@ -714,7 +836,14 @@ void TextEdit::backspace_at_cursor() {
int prev_line = cursor.column?cursor.line:cursor.line-1;
int prev_column = cursor.column?(cursor.column-1):(text[cursor.line-1].length());
- _remove_text(prev_line,prev_column,cursor.line,cursor.column);
+ if(auto_brace_completion_enabled &&
+ cursor.column > 0 &&
+ _is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
+ _consume_backspace_for_pair_symbol(prev_line, prev_column);
+ } else {
+ _remove_text(prev_line,prev_column,cursor.line,cursor.column);
+ }
+
cursor_set_line(prev_line);
cursor_set_column(prev_column);
@@ -976,7 +1105,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
return;
}
- if (k.scancode==KEY_RETURN) {
+ if (k.scancode==KEY_RETURN || k.scancode==KEY_TAB) {
_confirm_completion();
accept_event();
@@ -1002,11 +1131,17 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (cursor.column<text[cursor.line].length() && text[cursor.line][cursor.column]==k.unicode) {
//same char, move ahead
cursor_set_column(cursor.column+1);
+
} else {
//different char, go back
const CharType chr[2] = {k.unicode, 0};
- _insert_text_at_cursor(chr);
+ if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
+ _consume_pair_symbol(chr[0]);
+ } else {
+ _insert_text_at_cursor(chr);
+ }
}
+
_update_completion_candidates();
accept_event();
@@ -1113,7 +1248,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
default:
if (k.unicode>=32 && !k.mod.command && !k.mod.alt && !k.mod.meta)
clear=true;
-
+ if (auto_brace_completion_enabled && _is_pair_left_symbol(k.unicode))
+ clear=false;
}
if (unselect) {
@@ -1522,14 +1658,35 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (readonly)
break;
+ accept_event();
+ } else {
+
+ break;
+ }
+ }
+
+ if (!scancode_handled && !k.mod.command && !k.mod.alt) {
+
+ if (k.unicode>=32) {
+
+ if (readonly)
+ break;
+
const CharType chr[2] = {k.unicode, 0};
- _insert_text_at_cursor(chr);
+
+ if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
+ _consume_pair_symbol(chr[0]);
+ } else {
+ _insert_text_at_cursor(chr);
+ }
+
accept_event();
} else {
break;
}
}
+
if (!selection.selecting_test) {
@@ -1866,7 +2023,6 @@ void TextEdit::adjust_viewport_to_cursor() {
}
-
void TextEdit::cursor_set_column(int p_col) {
if (p_col<0)
@@ -2334,6 +2490,27 @@ String TextEdit::get_selection_text() const {
}
+String TextEdit::get_word_under_cursor() const {
+
+ int prev_cc = cursor.column;
+ while(prev_cc >0) {
+ bool is_char = _is_text_char(text[cursor.line][prev_cc-1]);
+ if (!is_char)
+ break;
+ --prev_cc;
+ }
+
+ int next_cc = cursor.column;
+ while(next_cc<text[cursor.line].length()) {
+ bool is_char = _is_text_char(text[cursor.line][next_cc]);
+ if(!is_char)
+ break;
+ ++ next_cc;
+ }
+ if (prev_cc == cursor.column || next_cc == cursor.column)
+ return "";
+ return text[cursor.line].substr(prev_cc, next_cc-prev_cc);
+}
DVector<int> TextEdit::_search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const {
@@ -2724,6 +2901,7 @@ void TextEdit::_update_completion_candidates() {
completion_current=completion_options[completion_index];
+#if 0 // even there's only one option, user still get the chance to choose using it or not
if (completion_options.size()==1) {
//one option to complete, just complete it automagically
_confirm_completion();
@@ -2732,6 +2910,9 @@ void TextEdit::_update_completion_candidates() {
return;
}
+#endif
+ if (completion_options.size()==1 && s==completion_options[0])
+ _cancel_completion();
completion_enabled=true;
@@ -2886,6 +3067,7 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_selection_to_line"),&TextEdit::get_selection_to_line);
ObjectTypeDB::bind_method(_MD("get_selection_to_column"),&TextEdit::get_selection_to_column);
ObjectTypeDB::bind_method(_MD("get_selection_text"),&TextEdit::get_selection_text);
+ ObjectTypeDB::bind_method(_MD("get_word_under_cursor"),&TextEdit::get_word_under_cursor);
ObjectTypeDB::bind_method(_MD("search","flags","from_line","from_column","to_line","to_column"),&TextEdit::_search_bind);
ObjectTypeDB::bind_method(_MD("undo"),&TextEdit::undo);
@@ -2989,6 +3171,7 @@ TextEdit::TextEdit() {
tooltip_obj=NULL;
line_numbers=false;
next_operation_is_complex=false;
+ auto_brace_completion_enabled=false;
}
TextEdit::~TextEdit(){
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 8e9651668b..7700bfd4d3 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -206,6 +206,8 @@ class TextEdit : public Control {
bool text_changed_dirty;
bool undo_enabled;
bool line_numbers;
+
+ bool auto_brace_completion_enabled;
uint64_t last_dblclk;
@@ -272,6 +274,10 @@ protected:
void _insert_text_at_cursor(const String& p_text);
void _input_event(const InputEvent& p_input);
void _notification(int p_what);
+
+ void _consume_pair_symbol(CharType ch);
+ void _consume_backspace_for_pair_symbol(int prev_line, int prev_column);
+
static void _bind_methods();
@@ -300,8 +306,11 @@ public:
String get_text();
String get_line(int line) const;
void backspace_at_cursor();
-
-
+
+ inline void set_auto_brace_completion(bool p_enabled) {
+ auto_brace_completion_enabled = p_enabled;
+ }
+
void cursor_set_column(int p_col);
void cursor_set_line(int p_row);
@@ -332,6 +341,8 @@ public:
int get_selection_to_column() const;
String get_selection_text() const;
+ String get_word_under_cursor() const;
+
bool search(const String &p_key,uint32_t p_search_flags, int p_from_line, int p_from_column,int &r_line,int &r_column) const;
void undo();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 0bbc2dc695..91769bbb82 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -728,6 +728,7 @@ void Viewport::set_as_render_target(bool p_enable){
render_target_texture_rid=RID();
}
+ render_target_texture->set_flags(render_target_texture->flags);
render_target_texture->emit_changed();
}
@@ -773,6 +774,18 @@ bool Viewport::get_render_target_vflip() const{
}
+void Viewport::set_render_target_filter(bool p_enable) {
+
+ render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0));
+
+}
+
+bool Viewport::get_render_target_filter() const{
+
+ return (render_target_texture->get_flags()&Texture::FLAG_FILTER)!=0;
+}
+
+
Matrix32 Viewport::_get_input_pre_xform() const {
Matrix32 pre_xf;
@@ -990,6 +1003,9 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
+ ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter);
+ ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter);
+
ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode);
ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode);
@@ -1020,6 +1036,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") );
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") );
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") );
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index cc7f93cfa3..d54b489843 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -113,6 +113,7 @@ friend class RenderTargetTexture;
bool transparent_bg;
bool render_target_vflip;
+ bool render_target_filter;
void _update_rect();
@@ -210,6 +211,9 @@ public:
void set_render_target_vflip(bool p_enable);
bool get_render_target_vflip() const;
+ void set_render_target_filter(bool p_enable);
+ bool get_render_target_filter() const;
+
void set_render_target_update_mode(RenderTargetUpdateMode p_mode);
RenderTargetUpdateMode get_render_target_update_mode() const;
Ref<RenderTargetTexture> get_render_target_texture() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 8fd39b0d74..f3d757b601 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -187,7 +187,10 @@
#include "scene/3d/area.h"
#include "scene/3d/physics_joint.h"
#include "scene/3d/multimesh_instance.h"
+#include "scene/3d/baked_light.h"
#include "scene/3d/ray_cast.h"
+#include "scene/3d/immediate_geometry.h"
+#include "scene/3d/sprite_3d.h"
#include "scene/3d/spatial_sample_player.h"
#include "scene/3d/spatial_stream_player.h"
#include "scene/3d/proximity_group.h"
@@ -371,6 +374,9 @@ void register_scene_types() {
ObjectTypeDB::register_type<InterpolatedCamera>();
ObjectTypeDB::register_type<TestCube>();
ObjectTypeDB::register_type<MeshInstance>();
+ ObjectTypeDB::register_type<ImmediateGeometry>();
+ ObjectTypeDB::register_type<Sprite3D>();
+ ObjectTypeDB::register_type<AnimatedSprite3D>();
ObjectTypeDB::register_virtual_type<Light>();
ObjectTypeDB::register_type<DirectionalLight>();
ObjectTypeDB::register_type<OmniLight>();
@@ -401,7 +407,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PathFollow>();
ObjectTypeDB::register_type<VisibilityNotifier>();
ObjectTypeDB::register_type<VisibilityEnabler>();
-
+ ObjectTypeDB::register_type<BakedLight>();
ObjectTypeDB::register_type<WorldEnvironment>();
//scenariofx
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 3e12c7a5b5..99447c0a0e 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -101,15 +101,21 @@ void Environment::_bind_methods() {
ObjectTypeDB::bind_method(_MD("fx_set_param","param","value"),&Environment::fx_set_param);
ObjectTypeDB::bind_method(_MD("fx_get_param","param"),&Environment::fx_get_param);
+ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA);
+
ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Texture RGBE,Cubemap RGBE"),_SCS("set_background"),_SCS("get_background"));
ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_COLOR);
ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_TEXTURE);
ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/cubemap",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CUBEMAP);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,128,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_ENERGY);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/scale",PROPERTY_HINT_RANGE,"0.001,16,0.001"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_SCALE);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/glow",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_GLOW);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_GLOW);
ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_passes",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_PASSES);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_scale",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_SCALE);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_strength",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_STRENGTH);
+ ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_blend_mode",PROPERTY_HINT_ENUM,"Additive,Screen,SoftLight"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_BLEND_MODE);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom_treshold",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM_TRESHOLD);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"dof_blur/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_DOF_BLUR);
@@ -178,9 +184,11 @@ void Environment::_bind_methods() {
BIND_CONSTANT( BG_PARAM_TEXTURE );
BIND_CONSTANT( BG_PARAM_CUBEMAP );
BIND_CONSTANT( BG_PARAM_ENERGY );
+ BIND_CONSTANT( BG_PARAM_GLOW );
BIND_CONSTANT( BG_PARAM_MAX );
+ BIND_CONSTANT( FX_FXAA );
BIND_CONSTANT( FX_GLOW );
BIND_CONSTANT( FX_DOF_BLUR );
BIND_CONSTANT( FX_HDR );
@@ -190,7 +198,14 @@ void Environment::_bind_methods() {
BIND_CONSTANT( FX_MAX );
+ BIND_CONSTANT( FX_BLUR_BLEND_MODE_ADDITIVE );
+ BIND_CONSTANT( FX_BLUR_BLEND_MODE_SCREEN );
+ BIND_CONSTANT( FX_BLUR_BLEND_MODE_SOFTLIGHT );
+
BIND_CONSTANT( FX_PARAM_GLOW_BLUR_PASSES );
+ BIND_CONSTANT( FX_PARAM_GLOW_BLUR_SCALE );
+ BIND_CONSTANT( FX_PARAM_GLOW_BLUR_STRENGTH );
+ BIND_CONSTANT( FX_PARAM_GLOW_BLUR_BLEND_MODE );
BIND_CONSTANT( FX_PARAM_GLOW_BLOOM);
BIND_CONSTANT( FX_PARAM_GLOW_BLOOM_TRESHOLD);
BIND_CONSTANT( FX_PARAM_DOF_BLUR_PASSES );
@@ -226,11 +241,14 @@ Environment::Environment() {
set_background_param(BG_PARAM_CUBEMAP,Ref<CubeMap>());
set_background_param(BG_PARAM_ENERGY,1.0);
set_background_param(BG_PARAM_SCALE,1.0);
+ set_background_param(BG_PARAM_GLOW,0.0);
for(int i=0;i<FX_MAX;i++)
set_enable_fx(Fx(i),false);
fx_set_param(FX_PARAM_GLOW_BLUR_PASSES,1);
+ fx_set_param(FX_PARAM_GLOW_BLUR_SCALE,1);
+ fx_set_param(FX_PARAM_GLOW_BLUR_STRENGTH,1);
fx_set_param(FX_PARAM_GLOW_BLOOM,0.0);
fx_set_param(FX_PARAM_GLOW_BLOOM_TRESHOLD,0.5);
fx_set_param(FX_PARAM_DOF_BLUR_PASSES,1);
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index c94c81b694..627fbb7cc0 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -56,10 +56,12 @@ public:
BG_PARAM_CUBEMAP=VS::ENV_BG_PARAM_CUBEMAP,
BG_PARAM_ENERGY=VS::ENV_BG_PARAM_ENERGY,
BG_PARAM_SCALE=VS::ENV_BG_PARAM_SCALE,
+ BG_PARAM_GLOW=VS::ENV_BG_PARAM_GLOW,
BG_PARAM_MAX=VS::ENV_BG_PARAM_MAX
};
enum Fx {
+ FX_FXAA=VS::ENV_FX_FXAA,
FX_GLOW=VS::ENV_FX_GLOW,
FX_DOF_BLUR=VS::ENV_FX_DOF_BLUR,
FX_HDR=VS::ENV_FX_HDR,
@@ -69,8 +71,17 @@ public:
FX_MAX=VS::ENV_FX_MAX,
};
+ enum FxBlurBlendMode {
+ FX_BLUR_BLEND_MODE_ADDITIVE,
+ FX_BLUR_BLEND_MODE_SCREEN,
+ FX_BLUR_BLEND_MODE_SOFTLIGHT,
+ };
+
enum FxParam {
FX_PARAM_GLOW_BLUR_PASSES=VS::ENV_FX_PARAM_GLOW_BLUR_PASSES,
+ FX_PARAM_GLOW_BLUR_SCALE=VS::ENV_FX_PARAM_GLOW_BLUR_SCALE,
+ FX_PARAM_GLOW_BLUR_STRENGTH=VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH,
+ FX_PARAM_GLOW_BLUR_BLEND_MODE=VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE,
FX_PARAM_GLOW_BLOOM=VS::ENV_FX_PARAM_GLOW_BLOOM,
FX_PARAM_GLOW_BLOOM_TRESHOLD=VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD,
FX_PARAM_DOF_BLUR_PASSES=VS::ENV_FX_PARAM_DOF_BLUR_PASSES,
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 637a816112..091a46d4ab 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -45,6 +45,7 @@ static const char*_hint_names[Material::HINT_MAX]={
"opaque_pre_zpass",
"no_shadow",
"no_depth_draw",
+ "no_alpha_depth_draw",
};
static const Material::Flag _flag_indices[Material::FLAG_MAX]={
@@ -158,7 +159,7 @@ void Material::_bind_methods() {
for(int i=0;i<HINT_MAX;i++)
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, String()+"hints/"+_hint_names[i] ),_SCS("set_hint"),_SCS("get_hint"),_hint_indices[i]);
- ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub" ), _SCS("set_blend_mode"),_SCS("get_blend_mode"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,PMAlpha" ), _SCS("set_blend_mode"),_SCS("get_blend_mode"));
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/line_width",PROPERTY_HINT_RANGE,"0.1,32.0,0.1" ), _SCS("set_line_width"),_SCS("get_line_width"));
@@ -175,6 +176,7 @@ void Material::_bind_methods() {
BIND_CONSTANT( HINT_OPAQUE_PRE_PASS );
BIND_CONSTANT( HINT_NO_SHADOW );
BIND_CONSTANT( HINT_NO_DEPTH_DRAW );
+ BIND_CONSTANT( HINT_NO_DEPTH_DRAW_FOR_ALPHA );
BIND_CONSTANT( HINT_MAX );
BIND_CONSTANT( SHADE_MODEL_LAMBERT );
@@ -189,6 +191,8 @@ void Material::_bind_methods() {
BIND_CONSTANT( BLEND_MODE_MIX );
BIND_CONSTANT( BLEND_MODE_ADD );
BIND_CONSTANT( BLEND_MODE_SUB );
+ BIND_CONSTANT( BLEND_MODE_MUL );
+ BIND_CONSTANT( BLEND_MODE_PREMULT_ALPHA );
}
@@ -206,6 +210,7 @@ Material::Material(const RID& p_material) {
for(int i=0;i<HINT_MAX;i++)
hints[i]=false;
+ hints[HINT_NO_DEPTH_DRAW_FOR_ALPHA]=true;
blend_mode=BLEND_MODE_MIX;
shade_model = SHADE_MODEL_LAMBERT;
@@ -363,14 +368,14 @@ Material::BlendMode FixedMaterial::get_detail_blend_mode() const {
}
void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) {
- ERR_FAIL_INDEX(p_flag,3);
+ ERR_FAIL_INDEX(p_flag,4);
fixed_flags[p_flag]=p_value;
VisualServer::get_singleton()->fixed_material_set_flag(material,(VS::FixedMaterialFlags)p_flag,p_value);
}
bool FixedMaterial::get_fixed_flag(FixedFlag p_flag) const {
- ERR_FAIL_INDEX_V(p_flag,3,false);
+ ERR_FAIL_INDEX_V(p_flag,4,false);
return fixed_flags[p_flag];
}
@@ -417,6 +422,7 @@ void FixedMaterial::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_ALPHA);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_point_size" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_POINT_SIZE);
+ ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/discard_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_DISCARD_ALPHA);
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/diffuse" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DIFFUSE);
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR );
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION );
@@ -455,6 +461,7 @@ void FixedMaterial::_bind_methods() {
BIND_CONSTANT( FLAG_USE_ALPHA );
BIND_CONSTANT( FLAG_USE_COLOR_ARRAY );
BIND_CONSTANT( FLAG_USE_POINT_SIZE );
+ BIND_CONSTANT( FLAG_DISCARD_ALPHA );
}
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 7bd8b70fa4..2057b3cac9 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -75,6 +75,7 @@ public:
BLEND_MODE_MUL = VS::MATERIAL_BLEND_MODE_MUL,
BLEND_MODE_ADD = VS::MATERIAL_BLEND_MODE_ADD,
BLEND_MODE_SUB = VS::MATERIAL_BLEND_MODE_SUB,
+ BLEND_MODE_PREMULT_ALPHA = VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA,
};
@@ -84,6 +85,7 @@ public:
HINT_OPAQUE_PRE_PASS=VS::MATERIAL_HINT_OPAQUE_PRE_PASS,
HINT_NO_SHADOW=VS::MATERIAL_HINT_NO_SHADOW,
HINT_NO_DEPTH_DRAW=VS::MATERIAL_HINT_NO_DEPTH_DRAW,
+ HINT_NO_DEPTH_DRAW_FOR_ALPHA=VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA,
HINT_MAX=VS::MATERIAL_HINT_MAX
};
@@ -158,6 +160,7 @@ public:
FLAG_USE_ALPHA=VS::FIXED_MATERIAL_FLAG_USE_ALPHA,
FLAG_USE_COLOR_ARRAY=VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,
FLAG_USE_POINT_SIZE=VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE,
+ FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA
};
private:
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 244ee09c22..c6e492fcb3 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -92,10 +92,23 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) {
return true;
}
- if (sname.begins_with("materials/")) {
+ if (sname.begins_with("surface_")) {
+
+ int sl=sname.find("/");
+ if (sl==-1)
+ return false;
+ int idx=sname.substr(8,sl-8).to_int()-1;
+ String what = sname.get_slice("/",1);
+ if (what=="material")
+ surface_set_material(idx,p_value);
+ else if (what=="name")
+ surface_set_name(idx,p_value);
+ return true;
+ }
- int idx=sname.get_slice("/",1).to_int()-1;
- surface_set_material(idx,p_value);
+ if (sname=="custom_aabb/custom_aabb") {
+
+ set_custom_aabb(p_value);
return true;
}
@@ -160,10 +173,21 @@ bool Mesh::_get(const StringName& p_name,Variant &r_ret) const {
r_ret = get_morph_target_mode();
return true;
- } else if (sname.begins_with("materials/")) {
+ } else if (sname.begins_with("surface_")) {
+
+ int sl=sname.find("/");
+ if (sl==-1)
+ return false;
+ int idx=sname.substr(8,sl-8).to_int()-1;
+ String what = sname.get_slice("/",1);
+ if (what=="material")
+ r_ret=surface_get_material(idx);
+ else if (what=="name")
+ r_ret=surface_get_name(idx);
+ return true;
+ } else if (sname=="custom_aabb/custom_aabb") {
- int idx=sname.get_slice("/",1).to_int()-1;
- r_ret=surface_get_material(idx);
+ r_ret=custom_aabb;
return true;
} else if (!sname.begins_with("surfaces"))
@@ -200,8 +224,12 @@ void Mesh::_get_property_list( List<PropertyInfo> *p_list) const {
for (int i=0;i<surfaces.size();i++) {
p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) );
- p_list->push_back( PropertyInfo( Variant::OBJECT,"materials/"+itos(i+1), PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
+ p_list->push_back( PropertyInfo( Variant::STRING,"surface_"+itos(i+1)+"/name", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ) );
+ p_list->push_back( PropertyInfo( Variant::OBJECT,"surface_"+itos(i+1)+"/material", PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
}
+
+ p_list->push_back( PropertyInfo( Variant::_AABB,"custom_aabb/custom_aabb" ) );
+
}
@@ -473,6 +501,19 @@ AABB Mesh::get_aabb() const {
return aabb;
}
+
+void Mesh::set_custom_aabb(const AABB& p_custom) {
+
+ custom_aabb=p_custom;
+ VS::get_singleton()->mesh_set_custom_aabb(mesh,custom_aabb);
+}
+
+AABB Mesh::get_custom_aabb() const {
+
+ return custom_aabb;
+}
+
+
DVector<Face3> Mesh::get_faces() const {
@@ -700,6 +741,8 @@ void Mesh::_bind_methods() {
ObjectTypeDB::bind_method(_MD("center_geometry"),&Mesh::center_geometry);
ObjectTypeDB::set_method_flags(get_type_static(),_SCS("center_geometry"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
+ ObjectTypeDB::bind_method(_MD("set_custom_aabb","aabb"),&Mesh::set_custom_aabb);
+ ObjectTypeDB::bind_method(_MD("get_custom_aabb"),&Mesh::get_custom_aabb);
BIND_CONSTANT( NO_INDEX_ARRAY );
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 3a11a8e171..5243163a4d 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -107,6 +107,7 @@ private:
AABB aabb;
MorphTargetMode morph_target_mode;
Vector<StringName> morph_targets;
+ AABB custom_aabb;
mutable Ref<TriangleMesh> triangle_mesh;
@@ -156,6 +157,9 @@ public:
void add_surface_from_mesh_data(const Geometry::MeshData& p_mesh_data);
+ void set_custom_aabb(const AABB& p_custom);
+ AABB get_custom_aabb() const;
+
AABB get_aabb() const;
virtual RID get_rid() const;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index d0c159e9f0..2856101674 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -32,57 +32,56 @@
#define EQ_VERTEX_DIST 0.00001
+bool SurfaceTool::Vertex::operator==(const Vertex& p_b) const {
-bool SurfaceTool::compare(const Vertex& p_a,const Vertex& p_b) const {
- if (p_a.vertex.distance_to(p_b.vertex)>EQ_VERTEX_DIST)
+ if (vertex!=p_b.vertex)
return false;
- if (format&Mesh::ARRAY_FORMAT_TEX_UV) {
+ if (uv!=p_b.uv)
+ return false;
- if (p_a.uv.distance_to(p_b.uv)>EQ_VERTEX_DIST)
- return false;
- }
+ if (uv2!=p_b.uv2)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_TEX_UV2) {
+ if (normal!=p_b.normal)
+ return false;
- if (p_a.uv2.distance_to(p_b.uv2)>EQ_VERTEX_DIST)
- return false;
- }
+ if (binormal!=p_b.binormal)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_NORMAL) {
- if (p_a.normal.distance_to(p_b.normal)>EQ_VERTEX_DIST)
- return false;
- }
+ if (color!=p_b.color)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_TANGENT) {
- if (p_a.binormal.distance_to(p_b.binormal)>EQ_VERTEX_DIST)
- return false;
- if (p_a.tangent.distance_to(p_b.tangent)>EQ_VERTEX_DIST)
+ if (bones.size()!=p_b.bones.size())
+ return false;
+
+ for(int i=0;i<bones.size();i++) {
+ if (bones[i]!=p_b.bones[i])
return false;
}
- if (format&Mesh::ARRAY_FORMAT_COLOR) {
- if (p_a.color!=p_b.color)
+ for(int i=0;i<weights.size();i++) {
+ if (weights[i]!=p_b.weights[i])
return false;
}
- if (format&Mesh::ARRAY_FORMAT_BONES) {
- for(int i=0;i<4;i++) {
- if (Math::abs(p_a.bones[i]-p_b.bones[i])>CMP_EPSILON)
- return false;
- }
- }
+ return true;
+}
- if (format&Mesh::ARRAY_FORMAT_WEIGHTS) {
- for(int i=0;i<4;i++) {
- if (Math::abs(p_a.weights[i]-p_b.weights[i])>CMP_EPSILON)
- return false;
- }
- }
+uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
- return true;
+ uint32_t h = hash_djb2_buffer((const uint8_t*)&p_vtx.vertex,sizeof(real_t)*3);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.normal,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.binormal,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.tangent,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv,sizeof(real_t)*2,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv2,sizeof(real_t)*2,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.color,sizeof(real_t)*4,h);
+ h = hash_djb2_buffer((const uint8_t*)p_vtx.bones.ptr(),p_vtx.bones.size()*sizeof(int),h);
+ h = hash_djb2_buffer((const uint8_t*)p_vtx.weights.ptr(),p_vtx.weights.size()*sizeof(float),h);
+ return h;
}
void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
@@ -186,6 +185,17 @@ void SurfaceTool::add_weights( const Vector<float>& p_weights) {
}
+void SurfaceTool::add_smooth_group(bool p_smooth) {
+
+ ERR_FAIL_COND(!begun);
+ if (index_array.size()) {
+ smooth_groups[index_array.size()]=p_smooth;
+ } else {
+
+ smooth_groups[vertex_array.size()]=p_smooth;
+ }
+}
+
void SurfaceTool::add_index( int p_index) {
@@ -377,79 +387,53 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
void SurfaceTool::index() {
-#if 0
- printf("indexing..\n");
- ERR_FAIL_COND( format & Surface::ARRAY_FORMAT_INDEX ); // already indexed
-
- index_array.clear();
- DVector< Vertex > indexed_vertex_array;
+ if (index_array.size())
+ return; //already indexed
- int vertex_array_len = vertex_array.size();
- vertex_array.read_lock();
- const Vertex*vertex_array_ptr = vertex_array.read();
- for (int i=0;i<vertex_array_len;i++) {
+ HashMap<Vertex,int,VertexHasher> indices;
+ List<Vertex> new_vertices;
- int index_pos=-1;
+ for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) {
- int indexed_vertex_array_len=indexed_vertex_array.size();
-
- if (indexed_vertex_array_len) {
-
- indexed_vertex_array.read_lock();
- const Vertex* indexed_vertex_array_ptr=indexed_vertex_array.read();
-
- for (int j=0;j<indexed_vertex_array_len;j++) {
-
- if (vertex_array_ptr[i].same_as(indexed_vertex_array_ptr[j])) {
-
- index_pos=j;
- break;
- }
- }
-
- indexed_vertex_array.read_unlock();
- }
-
- if (index_pos==-1) {
-
- index_pos=indexed_vertex_array.size();
- indexed_vertex_array.push_back(vertex_array_ptr[i]);
+ int *idxptr=indices.getptr(E->get());
+ int idx;
+ if (!idxptr) {
+ idx=indices.size();
+ new_vertices.push_back(E->get());
+ indices[E->get()]=idx;
} else {
-
- indexed_vertex_array.write_lock();
- indexed_vertex_array.write()[index_pos].normal+=vertex_array_ptr[i].normal;
- indexed_vertex_array.write()[index_pos].binormal+=vertex_array_ptr[i].binormal;
- indexed_vertex_array.write()[index_pos].tangent+=vertex_array_ptr[i].tangent;
- indexed_vertex_array.write_unlock();
+ idx=*idxptr;
}
- index_array.push_back(index_pos);
- }
-
- int idxvertsize=indexed_vertex_array.size();
- indexed_vertex_array.write_lock();
- Vertex* idxvert=indexed_vertex_array.write();
- for (int i=0;i<idxvertsize;i++) {
+ index_array.push_back(idx);
- idxvert[i].normal.normalize();
- idxvert[i].tangent.normalize();
- idxvert[i].binormal.normalize();
}
- indexed_vertex_array.write_unlock();
- vertex_array.read_unlock();
-
- format|=Surface::ARRAY_FORMAT_INDEX;
- vertex_array=indexed_vertex_array;
+ vertex_array.clear();
+ vertex_array=new_vertices;
- printf("indexing.. end\n");
-#endif
+ format|=Mesh::ARRAY_FORMAT_INDEX;
}
void SurfaceTool::deindex() {
+ if (index_array.size()==0)
+ return; //nothing to deindex
+ Vector< Vertex > varr;
+ varr.resize(vertex_array.size());
+ int idx=0;
+ for (List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) {
+ varr[idx++]=E->get();
+ }
+ vertex_array.clear();
+ for (List<int>::Element *E=index_array.front();E;E=E->next()) {
+
+ ERR_FAIL_INDEX(E->get(),varr.size());
+ vertex_array.push_back(varr[E->get()]);
+ }
+ format&=~Mesh::ARRAY_FORMAT_INDEX;
}
@@ -631,80 +615,250 @@ void SurfaceTool::append_from(const Ref<Mesh>& p_existing, int p_surface,const T
void SurfaceTool::generate_tangents() {
ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV));
+ ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL));
-#if 0
- int len=vertex_array.size();
- vertex_array.write_lock();
- Vertex *vertexptr=vertex_array.write();
-
- for (int i=0;i<len/3;i++) {
+ if (index_array.size()) {
+ Vector<List<Vertex>::Element*> vtx;
+ vtx.resize(vertex_array.size());
+ int idx=0;
+ for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
+ vtx[idx++]=E;
+ E->get().binormal=Vector3();
+ E->get().tangent=Vector3();
+ }
- Vector3 v1 = vertexptr[i*3+0].vertex;
- Vector3 v2 = vertexptr[i*3+1].vertex;
- Vector3 v3 = vertexptr[i*3+2].vertex;
+ for (List<int>::Element *E=index_array.front();E;) {
+
+ int i[3];
+ i[0]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+ i[1]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+ i[2]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+
+
+ Vector3 v1 = vtx[ i[0] ]->get().vertex;
+ Vector3 v2 = vtx[ i[1] ]->get().vertex;
+ Vector3 v3 = vtx[ i[2] ]->get().vertex;
+
+ Vector2 w1 = vtx[ i[0] ]->get().uv;
+ Vector2 w2 = vtx[ i[1] ]->get().uv;
+ Vector2 w3 = vtx[ i[2] ]->get().uv;
+
+
+ float x1 = v2.x - v1.x;
+ float x2 = v3.x - v1.x;
+ float y1 = v2.y - v1.y;
+ float y2 = v3.y - v1.y;
+ float z1 = v2.z - v1.z;
+ float z2 = v3.z - v1.z;
+
+ float s1 = w2.x - w1.x;
+ float s2 = w3.x - w1.x;
+ float t1 = w2.y - w1.y;
+ float t2 = w3.y - w1.y;
+
+ float r = (s1 * t2 - s2 * t1);
+
+ Vector3 binormal,tangent;
+
+ if (r==0) {
+ binormal=Vector3(0,0,0);
+ tangent=Vector3(0,0,0);
+ } else {
+ tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+ }
- Vector3 w1 = vertexptr[i*3+0].uv[0];
- Vector3 w2 = vertexptr[i*3+1].uv[0];
- Vector3 w3 = vertexptr[i*3+2].uv[0];
+ tangent.normalize();
+ binormal.normalize();
+ Vector3 normal=Plane( v1, v2, v3 ).normal;
+ Vector3 tangentp = tangent - normal * normal.dot( tangent );
+ Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
- float x1 = v2.x - v1.x;
- float x2 = v3.x - v1.x;
- float y1 = v2.y - v1.y;
- float y2 = v3.y - v1.y;
- float z1 = v2.z - v1.z;
- float z2 = v3.z - v1.z;
+ tangentp.normalize();
+ binormalp.normalize();
- float s1 = w2.x - w1.x;
- float s2 = w3.x - w1.x;
- float t1 = w2.y - w1.y;
- float t2 = w3.y - w1.y;
- float r = (s1 * t2 - s2 * t1);
+ for (int j=0;j<3;j++) {
+ vtx[ i[j] ]->get().binormal+=binormalp;
+ vtx[ i[j] ]->get().tangent+=tangentp;
- Vector3 binormal,tangent;
+ }
+ }
- if (r==0) {
- binormal=Vector3(0,0,0);
- tangent=Vector3(0,0,0);
- } else {
- tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r);
- binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r);
+ for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
+ E->get().binormal.normalize();
+ E->get().tangent.normalize();
}
- tangent.normalize();
- binormal.normalize();
- Vector3 normal=Plane( v1, v2, v3 ).normal;
- Vector3 tangentp = tangent - normal * normal.dot( tangent );
- Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
+ } else {
+
- tangentp.normalize();
- binormalp.normalize();
+ for (List<Vertex>::Element *E=vertex_array.front();E;) {
+ List< Vertex >::Element *v[3];
+ v[0]=E;
+ v[1]=v[0]->next();
+ ERR_FAIL_COND(!v[1]);
+ v[2]=v[1]->next();
+ ERR_FAIL_COND(!v[2]);
+ E=v[2]->next();
- for (int j=0;j<3;j++) {
- vertexptr[i*3+j].normal=normal;
- vertexptr[i*3+j].binormal=binormalp;
- vertexptr[i*3+j].tangent=tangentp;
+ Vector3 v1 = v[0]->get().vertex;
+ Vector3 v2 = v[1]->get().vertex;
+ Vector3 v3 = v[2]->get().vertex;
+
+ Vector2 w1 = v[0]->get().uv;
+ Vector2 w2 = v[1]->get().uv;
+ Vector2 w3 = v[2]->get().uv;
+
+
+ float x1 = v2.x - v1.x;
+ float x2 = v3.x - v1.x;
+ float y1 = v2.y - v1.y;
+ float y2 = v3.y - v1.y;
+ float z1 = v2.z - v1.z;
+ float z2 = v3.z - v1.z;
+
+ float s1 = w2.x - w1.x;
+ float s2 = w3.x - w1.x;
+ float t1 = w2.y - w1.y;
+ float t2 = w3.y - w1.y;
+
+ float r = (s1 * t2 - s2 * t1);
+
+ Vector3 binormal,tangent;
+
+ if (r==0) {
+ binormal=Vector3(0,0,0);
+ tangent=Vector3(0,0,0);
+ } else {
+ tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+ }
+
+ tangent.normalize();
+ binormal.normalize();
+ Vector3 normal=Plane( v1, v2, v3 ).normal;
+
+ Vector3 tangentp = tangent - normal * normal.dot( tangent );
+ Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
+
+ tangentp.normalize();
+ binormalp.normalize();
+
+
+ for (int j=0;j<3;j++) {
+ v[j]->get().binormal=binormalp;
+ v[j]->get().tangent=tangentp;
+
+ }
}
}
- format|=Surface::ARRAY_FORMAT_TANGENT;
- printf("adding tangents to the format\n");
+ format|=Mesh::ARRAY_FORMAT_TANGENT;
- vertex_array.write_unlock();
-#endif
}
-void SurfaceTool::generate_flat_normals() {
+void SurfaceTool::generate_normals() {
-}
-void SurfaceTool::generate_smooth_normals() {
+ ERR_FAIL_COND(primitive!=Mesh::PRIMITIVE_TRIANGLES);
+
+ bool was_indexed=index_array.size();
+
+ deindex();
+
+ HashMap<Vertex,Vector3,VertexHasher> vertex_hash;
+
+ int count=0;
+ bool smooth=false;
+ if (smooth_groups.has(0))
+ smooth=smooth_groups[0];
+
+ print_line("SMOOTH BEGIN? "+itos(smooth));
+
+ List< Vertex >::Element *B=vertex_array.front();
+ for(List< Vertex >::Element *E=B;E;) {
+
+ List< Vertex >::Element *v[3];
+ v[0]=E;
+ v[1]=v[0]->next();
+ ERR_FAIL_COND(!v[1]);
+ v[2]=v[1]->next();
+ ERR_FAIL_COND(!v[2]);
+ E=v[2]->next();
+
+ Vector3 normal = Plane(v[0]->get().vertex,v[1]->get().vertex,v[2]->get().vertex).normal;
+
+ if (smooth) {
+
+ for(int i=0;i<3;i++) {
+
+ Vector3 *lv=vertex_hash.getptr(v[i]->get());
+ if (!lv) {
+ vertex_hash.set(v[i]->get(),normal);
+ } else {
+ (*lv)+=normal;
+ }
+ }
+ } else {
+
+ for(int i=0;i<3;i++) {
+
+ v[i]->get().normal=normal;
+
+ }
+ }
+ count+=3;
+
+ if (smooth_groups.has(count) || !E) {
+
+ if (vertex_hash.size()) {
+
+ while (B!=E) {
+
+
+ Vector3* lv=vertex_hash.getptr(B->get());
+ if (lv) {
+ B->get().normal=lv->normalized();
+ }
+
+ B=B->next();
+ }
+
+ } else {
+ B=E;
+ }
+
+ vertex_hash.clear();
+ if (E) {
+ smooth=smooth_groups[count];
+ print_line("SMOOTH AT "+itos(count)+": "+itos(smooth));
+
+ }
+ }
+
+ }
+
+ format|=Mesh::ARRAY_FORMAT_NORMAL;
+
+ if (was_indexed) {
+ index();
+ smooth_groups.clear();
+ }
}
@@ -722,6 +876,7 @@ void SurfaceTool::clear() {
last_weights.clear();
index_array.clear();
vertex_array.clear();
+ smooth_groups.clear();
}
@@ -736,12 +891,12 @@ void SurfaceTool::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_uv2","uv2"),&SurfaceTool::add_uv2);
ObjectTypeDB::bind_method(_MD("add_bones","bones"),&SurfaceTool::add_bones);
ObjectTypeDB::bind_method(_MD("add_weights","weights"),&SurfaceTool::add_weights);
+ ObjectTypeDB::bind_method(_MD("add_smooth_group","smooth"),&SurfaceTool::add_smooth_group);
ObjectTypeDB::bind_method(_MD("set_material","material:Material"),&SurfaceTool::set_material);
ObjectTypeDB::bind_method(_MD("index"),&SurfaceTool::index);
ObjectTypeDB::bind_method(_MD("deindex"),&SurfaceTool::deindex);
- ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals);
- ObjectTypeDB::bind_method(_MD("generate_smooth_normals"),&SurfaceTool::generate_smooth_normals);
- ObjectTypeDB::bind_method(_MD("generate_tangents"),&SurfaceTool::generate_tangents);
+ ///ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals);
+ ObjectTypeDB::bind_method(_MD("generate_normals"),&SurfaceTool::generate_normals);
ObjectTypeDB::bind_method(_MD("commit:Mesh","existing:Mesh"),&SurfaceTool::commit,DEFVAL( RefPtr() ));
ObjectTypeDB::bind_method(_MD("clear"),&SurfaceTool::clear);
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 8f0fcaa01a..fe82d3a4ce 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -49,12 +49,17 @@ public:
Vector<int> bones;
Vector<float> weights;
+ bool operator==(const Vertex& p_vertex) const;
+
Vertex() { }
};
private:
- bool compare(const Vertex& p_a,const Vertex& p_b) const;
+
+ struct VertexHasher {
+ static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
+ };
bool begun;
bool first;
@@ -64,6 +69,7 @@ private:
//arrays
List< Vertex > vertex_array;
List< int > index_array;
+ Map<int,bool> smooth_groups;
//memory
Color last_color;
@@ -92,13 +98,13 @@ public:
void add_uv2( const Vector2& p_uv);
void add_bones( const Vector<int>& p_indices);
void add_weights( const Vector<float>& p_weights);
+ void add_smooth_group(bool p_smooth);
void add_index( int p_index);
void index();
void deindex();
- void generate_flat_normals();
- void generate_smooth_normals();
+ void generate_normals();
void generate_tangents();
void add_to_format(int p_flags) { format|=p_flags; }
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index baf6fa9d8d..5b31ba1f1b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -53,6 +53,13 @@ void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate);
}
+bool Texture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
+
+ r_rect=p_rect;
+ r_src_rect=p_src_rect;
+
+ return true;
+}
void Texture::_bind_methods() {
@@ -302,6 +309,16 @@ void ImageTexture::fix_alpha_edges() {
}
}
+void ImageTexture::premultiply_alpha() {
+
+ if (format==Image::FORMAT_RGBA /*&& !(flags&FLAG_CUBEMAP)*/) {
+
+ Image img = get_data();
+ img.premultiply_alpha();
+ set_data(img);
+ }
+}
+
bool ImageTexture::has_alpha() const {
return ( format==Image::FORMAT_GRAYSCALE_ALPHA || format==Image::FORMAT_INDEXED_ALPHA || format==Image::FORMAT_RGBA );
@@ -386,8 +403,10 @@ void ImageTexture::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_lossy_storage_quality","quality"),&ImageTexture::set_lossy_storage_quality);
ObjectTypeDB::bind_method(_MD("get_lossy_storage_quality"),&ImageTexture::get_lossy_storage_quality);
ObjectTypeDB::bind_method(_MD("fix_alpha_edges"),&ImageTexture::fix_alpha_edges);
+ ObjectTypeDB::bind_method(_MD("premultiply_alpha"),&ImageTexture::premultiply_alpha);
ObjectTypeDB::bind_method(_MD("set_size_override","size"),&ImageTexture::set_size_override);
ObjectTypeDB::set_method_flags(get_type_static(),_SCS("fix_alpha_edges"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
+ ObjectTypeDB::set_method_flags(get_type_static(),_SCS("premultiply_alpha"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
ObjectTypeDB::bind_method(_MD("_reload_hook","rid"),&ImageTexture::_reload_hook);
@@ -597,6 +616,42 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate);
}
+bool AtlasTexture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
+
+ Rect2 rc=region;
+
+ if (!atlas.is_valid())
+ return false;
+
+ Rect2 src=p_src_rect;
+ src.pos+=(rc.pos-margin.pos);
+ Rect2 src_c = rc.clip(src);
+ if (src_c.size==Size2())
+ return false;
+ Vector2 ofs = (src_c.pos-src.pos);
+
+ Vector2 scale = p_rect.size / p_src_rect.size;
+ if(scale.x < 0)
+ {
+ float mx = (margin.size.width - margin.pos.x);
+ mx -= margin.pos.x;
+ ofs.x = -(ofs.x + mx);
+ }
+ if(scale.y < 0)
+ {
+ float my = margin.size.height - margin.pos.y;
+ my -= margin.pos.y;
+ ofs.y = -(ofs.y + my);
+ }
+ Rect2 dr( p_rect.pos+ofs*scale,src_c.size*scale );
+
+
+
+ r_rect=dr;
+ r_src_rect=src_c;
+ return true;
+}
+
AtlasTexture::AtlasTexture() {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 6259362882..86ff246498 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -70,6 +70,7 @@ public:
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
+ virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
@@ -143,6 +144,7 @@ public:
float get_lossy_storage_quality() const;
void fix_alpha_edges();
+ void premultiply_alpha();
void set_size_override(const Size2& p_size);
@@ -190,6 +192,7 @@ public:
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
+ virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
AtlasTexture();
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index 5c54bd74e3..a8e4c80f89 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -137,5 +137,7 @@ SceneStringNames::SceneStringNames() {
drop_data = StaticCString::create("drop_data");
can_drop_data = StaticCString::create("can_drop_data");
+ _im_update = StaticCString::create("_im_update");
+ _queue_update = StaticCString::create("_queue_update");
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 6a4e58ed54..2286712250 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -145,6 +145,10 @@ public:
StringName play_play;
+ StringName _im_update;
+ StringName _queue_update;
+
+
};