summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/physics/collision_object_sw.cpp32
-rw-r--r--servers/physics/collision_object_sw.h2
-rw-r--r--servers/physics/physics_server_sw.cpp21
-rw-r--r--servers/physics/physics_server_sw.h4
-rw-r--r--servers/visual/shader_language.cpp136
-rw-r--r--servers/visual/shader_language.h22
6 files changed, 195 insertions, 22 deletions
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index ab716a8f6e..3af8b542fa 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "collision_object_sw.h"
+#include "servers/physics/physics_server_sw.h"
#include "space_sw.h"
void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform) {
@@ -39,8 +40,12 @@ void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform
s.bpid = 0; //needs update
shapes.push_back(s);
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) {
@@ -50,8 +55,11 @@ void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) {
shapes[p_index].shape = p_shape;
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_transform) {
@@ -59,8 +67,11 @@ void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_tran
shapes[p_index].xform = p_transform;
shapes[p_index].xform_inv = p_transform.affine_inverse();
- _update_shapes();
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::remove_shape(ShapeSW *p_shape) {
@@ -90,7 +101,11 @@ void CollisionObjectSW::remove_shape(int p_index) {
shapes[p_index].shape->remove_owner(this);
shapes.remove(p_index);
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
+ //_shapes_changed();
}
void CollisionObjectSW::_set_static(bool p_static) {
@@ -202,7 +217,8 @@ void CollisionObjectSW::_shape_changed() {
_shapes_changed();
}
-CollisionObjectSW::CollisionObjectSW(Type p_type) {
+CollisionObjectSW::CollisionObjectSW(Type p_type)
+ : pending_shape_update_list(this) {
_static = true;
type = p_type;
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index dc988aae86..67a8a44944 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -75,6 +75,8 @@ private:
Transform inv_transform;
bool _static;
+ SelfList<CollisionObjectSW> pending_shape_update_list;
+
void _update_shapes();
protected:
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 8d6f7b3fd8..2d46770924 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -763,6 +763,8 @@ void PhysicsServerSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_impulse(p_pos, p_impulse);
body->wakeup();
};
@@ -772,6 +774,8 @@ void PhysicsServerSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_imp
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_torque_impulse(p_impulse);
body->wakeup();
};
@@ -781,6 +785,8 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_v
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
Vector3 v = body->get_linear_velocity();
Vector3 axis = p_axis_velocity.normalized();
v -= axis * axis.dot(v);
@@ -793,6 +799,7 @@ void PhysicsServerSW::body_set_axis_lock(RID p_body, BodyAxisLock p_lock) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+
body->set_axis_lock(p_lock);
body->wakeup();
}
@@ -902,6 +909,8 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons
ERR_FAIL_COND_V(!body->get_space(), false);
ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+ _update_shapes();
+
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result);
}
@@ -1209,6 +1218,8 @@ bool PhysicsServerSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_a
void PhysicsServerSW::free(RID p_rid) {
+ _update_shapes(); //just in case
+
if (shape_owner.owns(p_rid)) {
ShapeSW *shape = shape_owner.get(p_rid);
@@ -1312,6 +1323,8 @@ void PhysicsServerSW::step(real_t p_step) {
if (!active)
return;
+ _update_shapes();
+
doing_sync = false;
last_step = p_step;
@@ -1409,6 +1422,14 @@ int PhysicsServerSW::get_process_info(ProcessInfo p_info) {
return 0;
}
+void PhysicsServerSW::_update_shapes() {
+
+ while (pending_shape_update_list.first()) {
+ pending_shape_update_list.first()->self()->_shape_changed();
+ pending_shape_update_list.remove(pending_shape_update_list.first());
+ }
+}
+
void PhysicsServerSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
CollCbkData *cbk = (CollCbkData *)p_userdata;
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 2e1fa7065a..99ba302acd 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -62,6 +62,10 @@ class PhysicsServerSW : public PhysicsServer {
mutable RID_Owner<JointSW> joint_owner;
//void _clear_query(QuerySW *p_query);
+ friend class CollisionObjectSW;
+ SelfList<CollisionObjectSW>::List pending_shape_update_list;
+ void _update_shapes();
+
public:
static PhysicsServerSW *singleton;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 0684cb1701..c7b02c92f7 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -79,7 +79,11 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"|",
"^",
"~",
- "++"
+ "++",
+ "--",
+ "?",
+ ":",
+ "++",
"--",
"()",
"construct",
@@ -3116,6 +3120,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
tk = _get_token();
+ VariableDeclarationNode *vardecl = alloc_node<VariableDeclarationNode>();
+ vardecl->datatype=type;
+ vardecl->precision=precision;
+
+ p_block->statements.push_back(vardecl);
+
while (true) {
if (tk.type != TK_IDENTIFIER) {
@@ -3133,8 +3143,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
var.type = type;
var.precision = precision;
var.line = tk_line;
+
p_block->variables[name] = var;
+ VariableDeclarationNode::Declaration decl;
+
+ decl.name=name;
+ decl.initializer=NULL;
+
tk = _get_token();
if (tk.type == TK_OP_ASSIGN) {
@@ -3143,22 +3159,19 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
if (!n)
return ERR_PARSE_ERROR;
- OperatorNode *assign = alloc_node<OperatorNode>();
- VariableNode *vnode = alloc_node<VariableNode>();
- vnode->name = name;
- vnode->datatype_cache = type;
- assign->arguments.push_back(vnode);
- assign->arguments.push_back(n);
- assign->op = OP_ASSIGN;
- p_block->statements.push_back(assign);
- tk = _get_token();
+ decl.initializer = n;
- if (!_validate_operator(assign)) {
- _set_error("Invalid assignment of '" + get_datatype_name(n->get_datatype()) + "' to '" + get_datatype_name(type) + "'");
+ if (var.type!=n->get_datatype()) {
+ _set_error("Invalid assignment of '" + get_datatype_name(n->get_datatype()) + "' to '" + get_datatype_name(var.type) + "'");
return ERR_PARSE_ERROR;
+
}
+ tk = _get_token();
+
}
+ vardecl->declarations.push_back(decl);
+
if (tk.type == TK_COMMA) {
tk = _get_token();
//another variable
@@ -3221,7 +3234,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
//if () {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after if");
+ _set_error("Expected '(' after while");
return ERR_PARSE_ERROR;
}
@@ -3243,7 +3256,64 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ Error err = _parse_block(block, p_builtin_types, true, true, true);
+ if (err)
+ return err;
+ } else if (tk.type == TK_CF_FOR) {
+ //if () {}
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after for");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_FOR;
+
+ BlockNode *init_block = alloc_node<BlockNode>();
+ init_block->parent_block = p_block;
+ init_block->single_statement=true;
+ cf->blocks.push_back(init_block);
+ if (_parse_block(init_block,p_builtin_types,true,false,false)!=OK) {
+ return ERR_PARSE_ERROR;
+ }
+
+ Node *n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ if (n->get_datatype()!=TYPE_BOOL) {
+ _set_error("Middle expression is expected to be boolean.");
+ return ERR_PARSE_ERROR;
+
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';' after middle expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ cf->expressions.push_back(n);
+
+ n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ cf->expressions.push_back(n);
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' after third expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(block, p_builtin_types, true, true, true);
if (err)
return err;
@@ -3320,6 +3390,44 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
}
p_block->statements.push_back(flow);
+ } else if (tk.type == TK_CF_BREAK) {
+
+
+ if (!p_can_break) {
+ //all is good
+ _set_error("Breaking is not allowed here");
+ }
+
+ ControlFlowNode *flow = alloc_node<ControlFlowNode>();
+ flow->flow_op = FLOW_OP_BREAK;
+
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ //all is good
+ _set_error("Expected ';' after break");
+ }
+
+ p_block->statements.push_back(flow);
+ } else if (tk.type == TK_CF_CONTINUE) {
+
+
+ if (!p_can_break) {
+ //all is good
+ _set_error("Contiuning is not allowed here");
+ }
+
+ ControlFlowNode *flow = alloc_node<ControlFlowNode>();
+ flow->flow_op = FLOW_OP_CONTINUE;
+
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ //all is good
+ _set_error("Expected ';' after continue");
+ }
+
+ p_block->statements.push_back(flow);
} else {
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index f00b4c5a97..50f5cebeaa 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -266,6 +266,7 @@ public:
TYPE_FUNCTION,
TYPE_BLOCK,
TYPE_VARIABLE,
+ TYPE_VARIABLE_DECLARATION,
TYPE_CONSTANT,
TYPE_OPERATOR,
TYPE_CONTROL_FLOW,
@@ -315,6 +316,25 @@ public:
}
};
+ struct VariableDeclarationNode : public Node {
+
+ DataPrecision precision;
+ DataType datatype;
+
+ struct Declaration {
+
+ StringName name;
+ Node *initializer;
+ };
+
+ Vector<Declaration> declarations;
+ virtual DataType get_datatype() const { return datatype; }
+
+ VariableDeclarationNode() {
+ type = TYPE_VARIABLE_DECLARATION;
+ }
+ };
+
struct ConstantNode : public Node {
DataType datatype;
@@ -346,10 +366,12 @@ public:
Map<StringName, Variable> variables;
List<Node *> statements;
+ bool single_statement;
BlockNode() {
type = TYPE_BLOCK;
parent_block = NULL;
parent_function = NULL;
+ single_statement=false;
}
};