Browse Source

More Bugfix...
-=-=-=-=-=-==

-Fix bug in camera follow script
-Fix negate operator not working in shader language
-Fix uninitialized pointer in raycast query API

Juan Linietsky 11 years ago
parent
commit
e0ce701c8c

+ 1 - 24
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)

+ 4 - 1
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)

+ 4 - 0
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;
 

+ 137 - 35
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;
 

+ 68 - 54
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 {