CollisionEvent CollisionGrid::cast(const ray& r, CollisionObject* ignore) {
	CollisionEvent e;
	e.intersected = false;
	std::list<vec2> grid_list;
	rayGridIntersections(r, grid_list);
	for(std::list<vec2>::iterator g = grid_list.begin(); g != grid_list.end(); g++) {
		int len = grid_list.size();
		int x = (*g)[0];
		int y = (*g)[1];
		if(x < 0) continue;
		if(x >= size_x) continue;
		if(y < 0) continue;
		if(y >= size_y) continue;

		std::list<CollisionObject*>& lst = grid[x+y*size_x];
		for(std::list<CollisionObject*>::iterator obj = lst.begin(); obj != lst.end(); obj++) {
			if(ignore == (*obj)) continue;
			Transformable* t = (Transformable*)((*obj)->script)->getLink(LINK_TRANSFORMABLE);
			vec3 p = t->getPosition();
			float radius = (*obj)->radius;
			vec2 closestP;
			float distance;
			if(!rayCircleIntersection(r, vec2(p[0], p[2]), radius, closestP, distance)) {
				continue;
			} else {
				e.distance = distance;
				e.intersected = true;
				e.obj_script = (*obj)->script;
				e.obj_type = (*obj)->type;
				return e;
			}
		}
	}
	return e;
}
CollisionEvent CollisionGrid::range_closest(const vec2& i, const float& range) {
	CollisionEvent e;
	e.intersected = false;
	float closest_dist_sq = 999999999.f;
	CollisionObject* closest_object = 0;
	
	int start_x = i[0]-range;
	if(start_x < 0) start_x = 0;
	int start_y = i[1]-range;
	if(start_y < 0) start_y = 0;
	int end_x = i[0]+range;
	if(end_x >= size_x) end_x = size_x-1;
	int end_y = i[0]+range;
	if(end_y >= size_y) end_y = size_y-1;

	float range_sq = range*range;

	for(int x=start_x; x<end_x; x++) {
		for(int y=start_y; y<end_y; y++) {
			std::list<CollisionObject*>& lst = grid[x+y*size_x];
			for(std::list<CollisionObject*>::iterator obj = lst.begin(); obj != lst.end(); obj++) {
				Transformable* t = (Transformable*)((*obj)->script->getLink(LINK_TRANSFORMABLE));
				vec2 p(t->getPosition()[0], t->getPosition()[2]);
				float radius = (*obj)->radius;
				float distance_sq = (p - i).length2();
				if(distance_sq <= range_sq && distance_sq < closest_dist_sq && !((*obj)->script->destroyOnNextFrame)) {
					closest_dist_sq = distance_sq;
					closest_object = (*obj);
				}
			}
		}
	}

	if(closest_object != 0) {
		e.intersected = true;
		e.distance = sqrt(closest_dist_sq);
		e.obj_script = closest_object->script;
		e.obj_type = closest_object->type;
	}

	return e;
}
void CollisionGrid::add(Script* script, int type, float radius) {
	Transformable* t = (Transformable*)script->getLink(LINK_TRANSFORMABLE);
	if(!t) return;

	vec3 pos = t->getPosition();
	int x = pos[0], y = pos[2];
	CollisionObject* obj = new CollisionObject;
	obj->script = script;
	obj->type = type;
	obj->radius = radius;
	objects.push_back(obj);
	script->setCollisionObject(obj);
	update(0.f);
}
std::list<CollisionEvent> CollisionGrid::range_all(const vec2& i, const float& range) {
	std::list<CollisionEvent> events;

	int start_x = i[0]-(range);
	if(start_x < 0) start_x = 0;
	int start_y = i[1]-(range);
	if(start_y < 0) start_y = 0;
	int end_x = i[0]+(range);
	if(end_x >= size_x) end_x = size_x-1;
	int end_y = i[0]+(range);
	if(end_y >= size_y) end_y = size_y-1;

	float range_sq = range*range;

	for(int x=start_x; x<end_x; x++) {
		for(int y=start_y; y<end_y; y++) {
			std::list<CollisionObject*>& lst = grid[x+y*size_x];
			for(std::list<CollisionObject*>::iterator obj = lst.begin(); obj != lst.end(); obj++) {
				Transformable* t = (Transformable*)((*obj)->script->getLink(LINK_TRANSFORMABLE));
				vec2 p = vec2(t->getPosition()[0], t->getPosition()[2]);
				float radius = (*obj)->radius;
				float distance_sq = (p - i).length2();
				if(distance_sq <= range_sq && !((*obj)->script->destroyOnNextFrame)) {
					CollisionEvent e;
					e.intersected = true;
					e.distance = sqrt(distance_sq);
					e.obj_script = (*obj)->script;
					e.obj_type = (*obj)->type;
					events.push_back(e);
				}
			}
		}
	}

	return events;
}
void CollisionGrid::update(float frameDelta) {
//if(!grid) return;

	for(boost::unordered_map<int, std::list<CollisionObject*> >::iterator lst = grid.begin(); lst != grid.end(); lst++) {
		lst->second.clear();
	}

//	memset(walk_grid, 0, sizeof(bool)*size_x*size_y);

	for(std::list<CollisionObject*>::iterator obj = objects.begin(); obj != objects.end(); obj++) {
		Transformable* t = (Transformable*)((*obj)->script->getLink(LINK_TRANSFORMABLE));
		vec3 p = t->getPosition();
		float r = (*obj)->radius;
		int x = p[0], y = p[2];
		walk_grid[x+y*size_x] = 1;
		grid[x+y*size_x].push_back(*obj);
	}
}
예제 #6
0
    Transformable::Transformable(const Transformable& other)
    {
        // We can only copy the layouts when they are strings
        Layout2d position = {other.getPosition()};
        Layout2d size = {other.getSize()};

        if (other.m_position.x.getImpl()->operation == LayoutImpl::Operation::String)
            position.x = other.m_position.x.getImpl()->stringExpression;
        if (other.m_position.y.getImpl()->operation == LayoutImpl::Operation::String)
            position.y = other.m_position.y.getImpl()->stringExpression;

        if (other.m_size.x.getImpl()->operation == LayoutImpl::Operation::String)
            size.x = other.m_size.x.getImpl()->stringExpression;
        if (other.m_size.y.getImpl()->operation == LayoutImpl::Operation::String)
            size.y = other.m_size.y.getImpl()->stringExpression;

        setPosition(position);
        setSize(size);
    }