diff options
-rw-r--r-- | demos/3d/kinematic_char/follow_camera.gd | 25 | ||||
-rw-r--r-- | demos/3d/platformer/follow_camera.gd | 5 | ||||
-rw-r--r-- | servers/physics/space_sw.cpp | 4 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 172 | ||||
-rw-r--r-- | servers/visual/shader_language.h | 122 |
5 files changed, 214 insertions, 114 deletions
diff --git a/demos/3d/kinematic_char/follow_camera.gd b/demos/3d/kinematic_char/follow_camera.gd index 60eef5787a..cf7172d7bb 100644 --- a/demos/3d/kinematic_char/follow_camera.gd +++ b/demos/3d/kinematic_char/follow_camera.gd @@ -24,7 +24,7 @@ func _fixed_process(dt): #regular delta follow #check ranges - + if (delta.length() < min_distance): delta = delta.normalized() * min_distance elif (delta.length() > max_distance): @@ -36,29 +36,6 @@ func _fixed_process(dt): if ( delta.y < min_height): delta.y = min_height - #check autoturn - - var ds = PhysicsServer.space_get_direct_state( get_world().get_space() ) - - - var col_left = ds.intersect_ray(target,target+Matrix3(up,deg2rad(autoturn_ray_aperture)).xform(delta),collision_exception) - var col = ds.intersect_ray(target,target,collision_exception) - var col_right = ds.intersect_ray(target,target+Matrix3(up,deg2rad(-autoturn_ray_aperture)).xform(delta),collision_exception) - - if (!col.empty()): - #if main ray was occluded, get camera closer, this is the worst case scenario - delta = col.position - target - elif (!col_left.empty() and col_right.empty()): - #if only left ray is occluded, turn the camera around to the right - delta = Matrix3(up,deg2rad(-dt*autoturn_speed)).xform(delta) - elif (col_left.empty() and !col_right.empty()): - #if only right ray is occluded, turn the camera around to the left - delta = Matrix3(up,deg2rad(dt*autoturn_speed)).xform(delta) - else: - #do nothing otherwise, left and right are occluded but center is not, so do not autoturn - pass - - #apply lookat pos = target + delta look_at_from_pos(pos,target,up) diff --git a/demos/3d/platformer/follow_camera.gd b/demos/3d/platformer/follow_camera.gd index 60eef5787a..3d18327df0 100644 --- a/demos/3d/platformer/follow_camera.gd +++ b/demos/3d/platformer/follow_camera.gd @@ -42,7 +42,7 @@ func _fixed_process(dt): var col_left = ds.intersect_ray(target,target+Matrix3(up,deg2rad(autoturn_ray_aperture)).xform(delta),collision_exception) - var col = ds.intersect_ray(target,target,collision_exception) + var col = ds.intersect_ray(target,target+delta,collision_exception) var col_right = ds.intersect_ray(target,target+Matrix3(up,deg2rad(-autoturn_ray_aperture)).xform(delta),collision_exception) if (!col.empty()): @@ -59,6 +59,9 @@ func _fixed_process(dt): pass #apply lookat + if (delta==Vector3()): + delta = (pos - target).normalized() * 0.0001 + pos = target + delta look_at_from_pos(pos,target,up) diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index ca3eea364a..68d6b464ab 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -123,6 +123,8 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto r_result.collider_id=res_obj->get_instance_id();
if (r_result.collider_id!=0)
r_result.collider=ObjectDB::get_instance(r_result.collider_id);
+ else
+ r_result.collider=NULL;
r_result.normal=res_normal;
r_result.position=res_point;
r_result.rid=res_obj->get_self();
@@ -173,6 +175,8 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo r_results[cc].collider_id=col_obj->get_instance_id();
if (r_results[cc].collider_id!=0)
r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
+ else
+ r_results[cc].collider=NULL;
r_results[cc].rid=col_obj->get_self();
r_results[cc].shape=shape_idx;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 489b5c3771..169429af81 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -1397,8 +1397,8 @@ ShaderLanguage::Operator ShaderLanguage::get_token_operator(TokenType p_type) { Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_expr) { - Vector<Node*> expressions; - Vector<TokenType> operators; + Vector<Expression> expression; + //Vector<TokenType> operators; while(true) { @@ -1605,34 +1605,33 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex parser.advance(); expr=varname; - } else if (parser.get_token_type()==TK_OP_NEG || parser.get_token_type()==TK_OP_NOT) { + } else if (parser.get_token_type()==TK_OP_SUB || parser.get_token_type()==TK_OP_NOT) { //single prefix operators TokenType token_type=parser.get_token_type(); parser.advance(); - Node *subexpr=NULL; - Error err = parse_expression(parser,p_parent,&subexpr); - if (err) - return err; + //Node *subexpr=NULL; + //Error err = parse_expression(parser,p_parent,&subexpr); + //if (err) + // return err; + + //OperatorNode *op = parser.create_node<OperatorNode>(p_parent); + + Expression e; + e.is_op=true; - OperatorNode *op = parser.create_node<OperatorNode>(p_parent); switch(token_type) { - case TK_OP_NEG: op->op=OP_NEG; break; - case TK_OP_NOT: op->op=OP_NOT; break; + case TK_OP_SUB: e.op=TK_OP_NEG; break; + case TK_OP_NOT: e.op=TK_OP_NOT; break; //case TK_OP_PLUS_PLUS: op->op=OP_PLUS_PLUS; break; //case TK_OP_MINUS_MINUS: op->op=OP_MINUS_MINUS; break; default: ERR_FAIL_V(ERR_BUG); } - op->arguments.push_back(subexpr); - - expr=validate_operator(parser,op); + expression.push_back(e); - if (!expr) { + continue; - parser.set_error("Invalid argument for negation operator"); - return ERR_PARSE_ERROR; - } } else { print_line("found bug?"); @@ -1798,48 +1797,64 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex } */ - - expressions.push_back(expr); + Expression e; + e.is_op=false; + e.node=expr; + expression.push_back(e); if (is_token_operator(parser.get_token_type())) { - operators.push_back(parser.get_token_type()); + Expression o; + o.is_op=true; + o.op=parser.get_token_type(); + expression.push_back(o); parser.advance(); } else { break; } } - ERR_FAIL_COND_V(expressions.size()!=(operators.size()+1),ERR_BUG); + /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */ - while(expressions.size()>1) { + while(expression.size()>1) { int next_op=-1; int min_priority=0xFFFFF; + bool is_unary=false; + + for(int i=0;i<expression.size();i++) { - for(int i=0;i<operators.size();i++) { + if (!expression[i].is_op) { + + continue; + } + + bool unary=false; int priority; - switch(operators[i]) { + switch(expression[i].op) { + + case TK_OP_NOT: priority=0; unary=true; break; + case TK_OP_NEG: priority=0; unary=true; break; - case TK_OP_MUL: priority=0; break; - case TK_OP_DIV: priority=0; break; + case TK_OP_MUL: priority=1; break; + case TK_OP_DIV: priority=1; break; - case TK_OP_ADD: priority=1; break; - case TK_OP_SUB: priority=1; break; + case TK_OP_ADD: priority=2; break; + case TK_OP_SUB: priority=2; break; // shift left/right =2 - case TK_OP_LESS: priority=3; break; - case TK_OP_LESS_EQUAL: priority=3; break; - case TK_OP_GREATER: priority=3; break; - case TK_OP_GREATER_EQUAL: priority=3; break; + case TK_OP_LESS: priority=4; break; + case TK_OP_LESS_EQUAL: priority=4; break; + case TK_OP_GREATER: priority=4; break; + case TK_OP_GREATER_EQUAL: priority=4; break; - case TK_OP_EQUAL: priority=4; break; - case TK_OP_NOT_EQUAL: priority=4; break; + case TK_OP_EQUAL: priority=5; break; + case TK_OP_NOT_EQUAL: priority=5; break; //bit and =5 //bit xor =6 @@ -1865,6 +1880,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex // <= is used for right to left next_op=i; min_priority=priority; + is_unary=unary; } } @@ -1872,7 +1888,92 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex ERR_FAIL_COND_V(next_op==-1,ERR_BUG); // OK! create operator.. + // OK! create operator.. + if (is_unary) { + + int expr_pos=next_op; + while(expression[expr_pos].is_op) { + + expr_pos++; + if (expr_pos==expression.size()) { + //can happen.. + parser.set_error("Unexpected end of expression.."); + return ERR_BUG; + } + } + + //consecutively do unary opeators + for(int i=expr_pos-1;i>=next_op;i--) { + + OperatorNode *op = parser.create_node<OperatorNode>(p_parent); + op->op=get_token_operator(expression[i].op); + op->arguments.push_back(expression[i+1].node); + + expression[i].is_op=false; + expression[i].node=validate_operator(parser,op); + if (!expression[i].node) { + + String at; + for(int i=0;i<op->arguments.size();i++) { + if (i>0) + at+=" and "; + at+=get_datatype_name(compute_node_type(op->arguments[i])); + + } + parser.set_error("Invalid argument to unary operator "+String(token_names[op->op])+": "+at); + return ERR_PARSE_ERROR; + } + expression.remove(i+1); + } + } else { + + if (next_op <1 || next_op>=(expression.size()-1)) { + parser.set_error("Parser bug.."); + ERR_FAIL_V(ERR_BUG); + } + + OperatorNode *op = parser.create_node<OperatorNode>(p_parent); + op->op=get_token_operator(expression[next_op].op); + + if (expression[next_op-1].is_op) { + + parser.set_error("Parser bug.."); + ERR_FAIL_V(ERR_BUG); + } + + if (expression[next_op+1].is_op) { + // this is not invalid and can really appear + // but it becomes invalid anyway because no binary op + // can be followed by an unary op in a valid combination, + // due to how precedence works, unaries will always dissapear first + + parser.set_error("Parser bug.."); + + } + + + op->arguments.push_back(expression[next_op-1].node); //expression goes as left + op->arguments.push_back(expression[next_op+1].node); //next expression goes as right + + //replace all 3 nodes by this operator and make it an expression + expression[next_op-1].node=validate_operator(parser,op); + if (!expression[next_op-1].node) { + + String at; + for(int i=0;i<op->arguments.size();i++) { + if (i>0) + at+=" and "; + at+=get_datatype_name(compute_node_type(op->arguments[i])); + + } + parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at); + return ERR_PARSE_ERROR; + } + expression.remove(next_op); + expression.remove(next_op); + } +#if 0 OperatorNode *op = parser.create_node<OperatorNode>(p_parent); op->op=get_token_operator(operators[next_op]); @@ -1896,10 +1997,11 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex expressions.remove(next_op+1); operators.remove(next_op); +#endif } - *r_expr=expressions[0]; + *r_expr=expression[0].node; return OK; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 36f5bd64c7..7e01368dd5 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -38,8 +38,66 @@ class ShaderLanguage { + + + public: + enum TokenType { + + TK_EMPTY, + TK_INDENTIFIER, + TK_TRUE, + TK_FALSE, + TK_REAL_CONSTANT, + TK_TYPE_VOID, + TK_TYPE_BOOL, + TK_TYPE_FLOAT, + TK_TYPE_VEC2, + TK_TYPE_VEC3, + TK_TYPE_VEC4, + TK_TYPE_MAT3, + TK_TYPE_MAT4, + TK_TYPE_TEXTURE, + TK_TYPE_CUBEMAP, + TK_TYPE_COLOR, + TK_OP_EQUAL, + TK_OP_NOT_EQUAL, + TK_OP_LESS, + TK_OP_LESS_EQUAL, + TK_OP_GREATER, + TK_OP_GREATER_EQUAL, + TK_OP_AND, + TK_OP_OR, + TK_OP_NOT, + TK_OP_ADD, + TK_OP_SUB, + TK_OP_MUL, + TK_OP_DIV, + TK_OP_NEG, + TK_OP_ASSIGN, + TK_OP_ASSIGN_ADD, + TK_OP_ASSIGN_SUB, + TK_OP_ASSIGN_MUL, + TK_OP_ASSIGN_DIV, + TK_CF_IF, + TK_CF_ELSE, + TK_CF_RETURN, + TK_BRACKET_OPEN, + TK_BRACKET_CLOSE, + TK_CURLY_BRACKET_OPEN, + TK_CURLY_BRACKET_CLOSE, + TK_PARENTHESIS_OPEN, + TK_PARENTHESIS_CLOSE, + TK_COMMA, + TK_SEMICOLON, + TK_PERIOD, + TK_UNIFORM, + TK_ERROR, + TK_MAX + }; + + /* COMPILER */ @@ -216,6 +274,16 @@ public: ProgramNode() { type=TYPE_PROGRAM; } }; + + struct Expression { + + bool is_op; + union { + TokenType op; + Node *node; + }; + }; + typedef Error (*CompileFunc)(void*,ProgramNode*); struct VarInfo { @@ -228,60 +296,6 @@ private: - enum TokenType { - - TK_EMPTY, - TK_INDENTIFIER, - TK_TRUE, - TK_FALSE, - TK_REAL_CONSTANT, - TK_TYPE_VOID, - TK_TYPE_BOOL, - TK_TYPE_FLOAT, - TK_TYPE_VEC2, - TK_TYPE_VEC3, - TK_TYPE_VEC4, - TK_TYPE_MAT3, - TK_TYPE_MAT4, - TK_TYPE_TEXTURE, - TK_TYPE_CUBEMAP, - TK_TYPE_COLOR, - TK_OP_EQUAL, - TK_OP_NOT_EQUAL, - TK_OP_LESS, - TK_OP_LESS_EQUAL, - TK_OP_GREATER, - TK_OP_GREATER_EQUAL, - TK_OP_AND, - TK_OP_OR, - TK_OP_NOT, - TK_OP_ADD, - TK_OP_SUB, - TK_OP_MUL, - TK_OP_DIV, - TK_OP_NEG, - TK_OP_ASSIGN, - TK_OP_ASSIGN_ADD, - TK_OP_ASSIGN_SUB, - TK_OP_ASSIGN_MUL, - TK_OP_ASSIGN_DIV, - TK_CF_IF, - TK_CF_ELSE, - TK_CF_RETURN, - TK_BRACKET_OPEN, - TK_BRACKET_CLOSE, - TK_CURLY_BRACKET_OPEN, - TK_CURLY_BRACKET_CLOSE, - TK_PARENTHESIS_OPEN, - TK_PARENTHESIS_CLOSE, - TK_COMMA, - TK_SEMICOLON, - TK_PERIOD, - TK_UNIFORM, - TK_ERROR, - TK_MAX - }; - static const char * token_names[TK_MAX]; struct Token { |