summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/3d/kinematic_char/follow_camera.gd25
-rw-r--r--demos/3d/platformer/follow_camera.gd5
-rw-r--r--servers/physics/space_sw.cpp4
-rw-r--r--servers/visual/shader_language.cpp172
-rw-r--r--servers/visual/shader_language.h122
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 {