Exemple #1
0
void PhysicsServerSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {

	ShapeSW *shape = shape_owner.get(p_shape);
	ERR_FAIL_COND(!shape);
	shape->set_custom_bias(p_bias);

}
Exemple #2
0
bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform& p_shape_xform,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {


	ShapeSW *shape = static_cast<PhysicsServerSW*>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape,0);

	AABB aabb = p_shape_xform.xform(shape->get_aabb());
	aabb=aabb.grow(p_margin);

	int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);

	_RestCallbackData rcd;
	rcd.best_len=0;
	rcd.best_object=NULL;
	rcd.best_shape=0;

	for(int i=0;i<amount;i++) {


		if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
			continue;

		const CollisionObjectSW *col_obj=space->intersection_query_results[i];
		int shape_idx=space->intersection_query_subindex_results[i];

		if (p_exclude.has( col_obj->get_self() ))
			continue;

		rcd.object=col_obj;
		rcd.shape=shape_idx;
		bool sc = CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),_rest_cbk_result,&rcd,NULL,p_margin);
		if (!sc)
			continue;


	}

	if (rcd.best_len==0)
		return false;

	r_info->collider_id=rcd.best_object->get_instance_id();
	r_info->shape=rcd.best_shape;
	r_info->normal=rcd.best_normal;
	r_info->point=rcd.best_contact;
	r_info->rid=rcd.best_object->get_self();
	if (rcd.best_object->get_type()==CollisionObjectSW::TYPE_BODY) {

		const BodySW *body = static_cast<const BodySW*>(rcd.best_object);
		Vector3 rel_vec = r_info->point-body->get_transform().get_origin();
		r_info->linear_velocity = body->get_linear_velocity() +
				(body->get_angular_velocity()).cross(body->get_transform().origin-rcd.best_contact);// * mPos);


	} else {
		r_info->linear_velocity=Vector3();
	}

	return true;
}
Exemple #3
0
void PhysicsServerSW::shape_set_data(RID p_shape, const Variant& p_data) {

	ShapeSW *shape = shape_owner.get(p_shape);
	ERR_FAIL_COND(!shape);
	shape->set_data(p_data);


};
Exemple #4
0
bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform& p_shape_xform,float p_margin,Vector3 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask){

	if (p_result_max<=0)
		return 0;

	ShapeSW *shape = static_cast<PhysicsServerSW*>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape,0);

	AABB aabb = p_shape_xform.xform(shape->get_aabb());
	aabb=aabb.grow(p_margin);

	int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);

	bool collided=false;
	int cc=0;
	r_result_count=0;

	PhysicsServerSW::CollCbkData cbk;
	cbk.max=p_result_max;
	cbk.amount=0;
	cbk.ptr=r_results;
	CollisionSolverSW::CallbackResult cbkres=NULL;

	PhysicsServerSW::CollCbkData *cbkptr=NULL;
	if (p_result_max>0) {
		cbkptr=&cbk;
		cbkres=PhysicsServerSW::_shape_col_cbk;
	}


	for(int i=0;i<amount;i++) {

		if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
			continue;

		const CollisionObjectSW *col_obj=space->intersection_query_results[i];
		int shape_idx=space->intersection_query_subindex_results[i];

		if (p_exclude.has( col_obj->get_self() )) {
			continue;
		}

		//print_line("AGAINST: "+itos(col_obj->get_self().get_id())+":"+itos(shape_idx));
		//print_line("THE ABBB: "+(col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).xform(col_obj->get_shape(shape_idx)->get_aabb()));

		if (CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),cbkres,cbkptr,NULL,p_margin)) {
			collided=true;
		}

	}

	r_result_count=cbk.amount;

	return collided;

}
Exemple #5
0
RID PhysicsServerSW::body_get_shape(RID p_body, int p_shape_idx) const {

	BodySW *body = body_owner.get(p_body);
	ERR_FAIL_COND_V(!body,RID());

	ShapeSW *shape = body->get_shape(p_shape_idx);
	ERR_FAIL_COND_V(!shape,RID());

	return shape->get_self();
}
Exemple #6
0
RID PhysicsServerSW::area_get_shape(RID p_area, int p_shape_idx) const {

	AreaSW *area = area_owner.get(p_area);
	ERR_FAIL_COND_V(!area,RID());

	ShapeSW *shape = area->get_shape(p_shape_idx);
	ERR_FAIL_COND_V(!shape,RID());

	return shape->get_self();
}
void PhysicsServerSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {

	BodySW *body = body_owner.get(p_body);
	ERR_FAIL_COND(!body);

	ShapeSW *shape = shape_owner.get(p_shape);
	ERR_FAIL_COND(!shape);
	ERR_FAIL_COND(!shape->is_configured());

	body->set_shape(p_shape_idx, shape);
}
void PhysicsServerSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {

	AreaSW *area = area_owner.get(p_area);
	ERR_FAIL_COND(!area);

	ShapeSW *shape = shape_owner.get(p_shape);
	ERR_FAIL_COND(!shape);
	ERR_FAIL_COND(!shape->is_configured());

	area->set_shape(p_shape_idx, shape);
}
RID PhysicsServerSW::shape_create(ShapeType p_shape) {

	ShapeSW *shape = NULL;
	switch (p_shape) {

		case SHAPE_PLANE: {

			shape = memnew(PlaneShapeSW);
		} break;
		case SHAPE_RAY: {

			shape = memnew(RayShapeSW);
		} break;
		case SHAPE_SPHERE: {

			shape = memnew(SphereShapeSW);
		} break;
		case SHAPE_BOX: {

			shape = memnew(BoxShapeSW);
		} break;
		case SHAPE_CAPSULE: {

			shape = memnew(CapsuleShapeSW);
		} break;
		case SHAPE_CYLINDER: {

			ERR_EXPLAIN("CylinderShape is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
			ERR_FAIL_V(RID());
		} break;
		case SHAPE_CONVEX_POLYGON: {

			shape = memnew(ConvexPolygonShapeSW);
		} break;
		case SHAPE_CONCAVE_POLYGON: {

			shape = memnew(ConcavePolygonShapeSW);
		} break;
		case SHAPE_HEIGHTMAP: {

			shape = memnew(HeightMapShapeSW);
		} break;
		case SHAPE_CUSTOM: {

			ERR_FAIL_V(RID());

		} break;
	}

	RID id = shape_owner.make_rid(shape);
	shape->set_self(id);

	return id;
};
Exemple #10
0
int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transform& p_xform,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {

	if (p_result_max<=0)
		return 0;

	ShapeSW *shape = static_cast<PhysicsServerSW*>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape,0);

	Rect3 aabb = p_xform.xform(shape->get_aabb());

	int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);

	int cc=0;

	//Transform ai = p_xform.affine_inverse();

	for(int i=0;i<amount;i++) {

		if (cc>=p_result_max)
			break;

		if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
			continue;

		//area cant be picked by ray (default)

		if (p_exclude.has( space->intersection_query_results[i]->get_self()))
			continue;


		const CollisionObjectSW *col_obj=space->intersection_query_results[i];
		int shape_idx=space->intersection_query_subindex_results[i];

		if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0))
			continue;

		if (r_results) {
			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;
		}

		cc++;

	}

	return cc;

}
Exemple #11
0
RID PhysicsServerSW::shape_create(ShapeType p_shape) {

	ShapeSW *shape = NULL;
	switch (p_shape) {

		case SHAPE_PLANE: {

			shape = memnew(PlaneShapeSW);
		} break;
		case SHAPE_RAY: {

			shape = memnew(RayShapeSW);
		} break;
		case SHAPE_SPHERE: {

			shape = memnew(SphereShapeSW);
		} break;
		case SHAPE_BOX: {

			shape = memnew(BoxShapeSW);
		} break;
		case SHAPE_CAPSULE: {

			shape = memnew(CapsuleShapeSW);
		} break;
		case SHAPE_CONVEX_POLYGON: {

			shape = memnew(ConvexPolygonShapeSW);
		} break;
		case SHAPE_CONCAVE_POLYGON: {

			shape = memnew(ConcavePolygonShapeSW);
		} break;
		case SHAPE_HEIGHTMAP: {

			shape = memnew(HeightMapShapeSW);
		} break;
		case SHAPE_CUSTOM: {

			ERR_FAIL_V(RID());

		} break;
	}

	RID id = shape_owner.make_rid(shape);
	shape->set_self(id);

	return id;
};
Exemple #12
0
Vector3 PhysicsDirectSpaceStateSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {

	CollisionObjectSW *obj = PhysicsServerSW::singleton->area_owner.getornull(p_object);
	if (!obj) {
		obj = PhysicsServerSW::singleton->body_owner.getornull(p_object);
	}
	ERR_FAIL_COND_V(!obj, Vector3());

	ERR_FAIL_COND_V(obj->get_space() != space, Vector3());

	float min_distance = 1e20;
	Vector3 min_point;

	bool shapes_found = false;

	for (int i = 0; i < obj->get_shape_count(); i++) {

		if (obj->is_shape_set_as_disabled(i))
			continue;

		Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i);
		ShapeSW *shape = obj->get_shape(i);

		Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point));
		point = shape_xform.xform(point);

		float dist = point.distance_to(p_point);
		if (dist < min_distance) {
			min_distance = dist;
			min_point = point;
		}
		shapes_found = true;
	}

	if (!shapes_found) {
		return obj->get_transform().origin; //no shapes found, use distance to origin.
	} else {
		return min_point;
	}
}
Exemple #13
0
void PhysicsServerSW::free(RID p_rid) {

	if (shape_owner.owns(p_rid)) {

		ShapeSW *shape = shape_owner.get(p_rid);

		while(shape->get_owners().size()) {
			ShapeOwnerSW *so=shape->get_owners().front()->key();
			so->remove_shape(shape);
		}

		shape_owner.free(p_rid);
		memdelete(shape);
	} else if (body_owner.owns(p_rid)) {

		BodySW *body = body_owner.get(p_rid);

//		if (body->get_state_query())
//			_clear_query(body->get_state_query());

//		if (body->get_direct_state_query())
//			_clear_query(body->get_direct_state_query());

		body->set_space(NULL);


		while( body->get_shape_count() ) {

			body->remove_shape(0);
		}

		while (body->get_constraint_map().size()) {
			RID self = body->get_constraint_map().front()->key()->get_self();
			ERR_FAIL_COND(!self.is_valid());
			free(self);
		}

		body_owner.free(p_rid);
		memdelete(body);

	} else if (area_owner.owns(p_rid)) {

		AreaSW *area = area_owner.get(p_rid);

//		if (area->get_monitor_query())
//			_clear_query(area->get_monitor_query());

		area->set_space(NULL);

		while( area->get_shape_count() ) {

			area->remove_shape(0);
		}

		area_owner.free(p_rid);
		memdelete(area);
	} else if (space_owner.owns(p_rid)) {

		SpaceSW *space = space_owner.get(p_rid);

		while(space->get_objects().size()) {
			CollisionObjectSW *co = (CollisionObjectSW *)space->get_objects().front()->get();
			co->set_space(NULL);
		}

		active_spaces.erase(space);
		free(space->get_default_area()->get_self());
		free(space->get_static_global_body());

		space_owner.free(p_rid);
		memdelete(space);
	} else if (joint_owner.owns(p_rid)) {

		JointSW *joint = joint_owner.get(p_rid);

		for(int i=0;i<joint->get_body_count();i++) {

			joint->get_body_ptr()[i]->remove_constraint(joint);
		}
		joint_owner.free(p_rid);
		memdelete(joint);

	} else {

		ERR_EXPLAIN("Invalid ID");
		ERR_FAIL();
	}


};
Exemple #14
0
bool PhysicsDirectSpaceStateSW::cast_motion(const RID& p_shape, const Transform& p_xform,const Vector3& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask,ShapeRestInfo *r_info) {



	ShapeSW *shape = static_cast<PhysicsServerSW*>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape,false);

	AABB aabb = p_xform.xform(shape->get_aabb());
	aabb=aabb.merge(AABB(aabb.pos+p_motion,aabb.size)); //motion
	aabb=aabb.grow(p_margin);

	//if (p_motion!=Vector3())
	//	print_line(p_motion);

	int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);

	float best_safe=1;
	float best_unsafe=1;

	Transform xform_inv = p_xform.affine_inverse();
	MotionShapeSW mshape;
	mshape.shape=shape;
	mshape.motion=xform_inv.basis.xform(p_motion);

	bool best_first=true;

	Vector3 closest_A,closest_B;

	for(int i=0;i<amount;i++) {


		if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
			continue;

		if (p_exclude.has( space->intersection_query_results[i]->get_self()))
			continue; //ignore excluded


		const CollisionObjectSW *col_obj=space->intersection_query_results[i];
		int shape_idx=space->intersection_query_subindex_results[i];

		Vector3 point_A,point_B;
		Vector3 sep_axis=p_motion.normalized();

		Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
		//test initial overlap, does it collide if going all the way?
		if (CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) {
			//print_line("failed motion cast (no collision)");
			continue;
		}


		//test initial overlap
#if 0
		if (CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,NULL,NULL,&sep_axis)) {
			print_line("failed initial cast (collision at begining)");
			return false;
		}
#else
		sep_axis=p_motion.normalized();

		if (!CollisionSolverSW::solve_distance(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) {
			//print_line("failed motion cast (no collision)");
			return false;
		}
#endif


		//just do kinematic solving
		float low=0;
		float hi=1;
		Vector3 mnormal=p_motion.normalized();

		for(int i=0;i<8;i++) { //steps should be customizable..

			Transform xfa = p_xform;
			float ofs = (low+hi)*0.5;

			Vector3 sep=mnormal; //important optimization for this to work fast enough

			mshape.motion=xform_inv.basis.xform(p_motion*ofs);

			Vector3 lA,lB;

			bool collided = !CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,lA,lB,aabb,&sep);

			if (collided) {

				//print_line(itos(i)+": "+rtos(ofs));
				hi=ofs;
			} else {

				point_A=lA;
				point_B=lB;
				low=ofs;
			}
		}

		if (low<best_safe) {
			best_first=true; //force reset
			best_safe=low;
			best_unsafe=hi;
		}

		if (r_info && (best_first || (point_A.distance_squared_to(point_B) < closest_A.distance_squared_to(closest_B) && low<=best_safe))) {
			closest_A=point_A;
			closest_B=point_B;
			r_info->collider_id=col_obj->get_instance_id();
			r_info->rid=col_obj->get_self();
			r_info->shape=shape_idx;
			r_info->point=closest_B;
			r_info->normal=(closest_A-closest_B).normalized();
			best_first=false;
			if (col_obj->get_type()==CollisionObjectSW::TYPE_BODY) {
				const BodySW *body=static_cast<const BodySW*>(col_obj);
				r_info->linear_velocity= body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - closest_B);
			}

		}


	}

	p_closest_safe=best_safe;
	p_closest_unsafe=best_unsafe;	

	return true;
}