示例#1
0
文件: turret.cpp 项目: FrostHand/TiGa
void TurretControl::update(float dt)
{
	for(auto it=this->cmdOut.begin();it!=cmdOut.end();++it)
	{
		WeaponTurret *weapon=dynamic_cast<WeaponTurret*>(*it);
		//if(!weapon)return;
		float targ=weapon->getAngle(target);
		float curr=weapon->getAngle();
		float deltaAngle=targ-curr;
		float deltaVel=dt*turret->velocity;
		if(weapon->fullTurn())
		{
			if(deltaAngle>= 180)deltaAngle-=360;
			if(deltaAngle<=-180)deltaAngle+=360;
		}
		if(flagTest(lstate,Shoot) && fabs(deltaAngle) < minError)
		{		
			weapon->query_Action(weapon->portShoot);
			//if(flagTest(lstate,ShootOnce))flagSet(lstate,Shoot,false);		
		}
		if(flagTest(lstate,Aim))
		{
			//localBuffer.rewind();
			//localBuffer.write(fabs(deltaAngle)<deltaVel?deltaAngle/deltaVel:deltaAngle);
			//localBuffer.flip();
			weapon->query_Direction(weapon->portTurn,dcmdDir_inc,fabs(deltaAngle)<deltaVel?deltaAngle/deltaVel:deltaAngle);
			//weapon->query(DeviceCmd::dcmdParam,&localBuffer);
			//localBuffer.flip();
		}
	}
}
示例#2
0
void Grid::findAll(vector<int> &out, const FBox &box, int ignored_id, int flags) const {
	IRect grid_box = nodeCoords(box);

	for(int y = grid_box.min.y; y <= grid_box.max.y; y++)
		for(int x = grid_box.min.x; x <= grid_box.max.x; x++) {
			int node_id = nodeAt(int2(x, y));
			const Node &node = m_nodes[node_id];

			if(!flagTest(node.obj_flags, flags) || !areOverlapping(box, node.bbox))
				continue;
			bool anything_found = false;

			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, ignored_id, flags);

			for(int n = 0; n < count; n++)
				if(areOverlapping(box, objects[n]->bbox)) {
					if(objects[n]->node_id == -1)
						disableOverlap(objects[n]);
					out.push_back(objects[n] - &m_objects[0]);
					anything_found = true;
				}

			if(!anything_found && node.is_dirty)
				updateNode(node_id);	
		}

	clearDisables();
}
示例#3
0
int Grid::pixelIntersect(const int2 &screen_pos, bool (*pixelTest)(const ObjectDef&, const int2&), int flags) const {
	IRect grid_box(0, 0, m_size.x, m_size.y);
	
	int best = -1;
	FBox best_box;

	for(int y = grid_box.min.y; y < grid_box.max.y; y++) {
		const int2 &row_rect = m_row_rects[y];
		if(row_rect.x >= screen_pos.y || row_rect.y <= screen_pos.y)
			continue;

		for(int x = grid_box.min.x; x < grid_box.max.x; x++) {
			int node_id = nodeAt(int2(x, y));
			const Node &node = m_nodes[node_id];

			if(!flagTest(node.obj_flags, flags) || !node.rect.isInside(screen_pos))
				continue;
			if(node.is_dirty)
				updateNode(node_id);	

			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, -1, flags);

			for(int n = 0; n < count; n++)
				if(objects[n]->rect().isInside(screen_pos) && pixelTest(*objects[n], screen_pos)) {
					if(best == -1 || drawingOrder(objects[n]->bbox, best_box) == 1) {
						best = objects[n] - &m_objects[0];
						best_box = objects[n]->bbox;
					}
				}
		}
	}

	return best;
}
示例#4
0
void Grid::findAll(vector<int> &out, const IRect &view_rect, int flags) const {
	IRect grid_box(0, 0, m_size.x, m_size.y);

	for(int y = grid_box.min.y; y < grid_box.max.y; y++) {
		const int2 &row_rect = m_row_rects[y];
		if(row_rect.x >= view_rect.max.y || row_rect.y <= view_rect.min.y)
			continue;
		
		for(int x = grid_box.min.x; x < grid_box.max.x; x++) {
			int node_id = nodeAt(int2(x, y));
			const Node &node = m_nodes[node_id];
	
			if(!flagTest(node.obj_flags, flags) || !areOverlapping(view_rect, node.rect))
				continue;

			bool anything_found = false;
			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, -1, flags);

			for(int n = 0; n < count; n++) {
				if(areOverlapping(view_rect, objects[n]->rect())) {
					if(objects[n]->node_id == -1)
						disableOverlap(objects[n]);
					out.push_back(objects[n] - &m_objects[0]);
					anything_found = true;
				}
			}

			if(!anything_found && node.is_dirty)
				updateNode(node_id);	
		}
	}

	clearDisables();
}
示例#5
0
int Grid::findAny(const FBox &box, int ignored_id, int flags) const {
	IRect grid_box = nodeCoords(box);

	for(int y = grid_box.min.y; y <= grid_box.max.y; y++)
		for(int x = grid_box.min.x; x <= grid_box.max.x; x++) {
			int node_id = nodeAt(int2(x, y));
			const Node &node = m_nodes[node_id];

			if(!node.size || !flagTest(node.obj_flags, flags) || !areOverlapping(box, node.bbox))
				continue;

			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, ignored_id, flags);

			for(int n = 0; n < count; n++)
				if(areOverlapping(box, objects[n]->bbox))
					return objects[n] - &m_objects[0];

			if(node.is_dirty)
				updateNode(node_id);	
		}

	return -1;
}
示例#6
0
pair<int, float> Grid::trace(const Ray &ray, float tmin, float tmax, int ignored_id, int flags) const {
	float3 p1 = ray.at(tmin), p2 = ray.at(tmax);
	int2 pos = worldToGrid((int2)p1.xz()), end = worldToGrid((int2)p2.xz());
	
	//TODO: verify for rays going out of grid space
	if(!isInsideGrid(pos) || !isInsideGrid(end))
		return make_pair(-1, constant::inf);

	// Algorithm idea from: RTCD by Christer Ericson
	int dx = end.x > pos.x? 1 : end.x < pos.x? -1 : 0;
	int dz = end.y > pos.y? 1 : end.y < pos.y? -1 : 0;

	float cell_size = (float)node_size;
	float inv_cell_size = 1.0f / cell_size;
	float lenx = fabs(p2.x - p1.x);
	float lenz = fabs(p2.z - p1.z);

	float minx = float(node_size) * floorf(p1.x * inv_cell_size), maxx = minx + cell_size;
	float minz = float(node_size) * floorf(p1.z * inv_cell_size), maxz = minz + cell_size;
	float tx = (p1.x > p2.x? p1.x - minx : maxx - p1.x) / lenx;
	float tz = (p1.z > p2.z? p1.z - minz : maxz - p1.z) / lenz;

	float deltax = cell_size / lenx;
	float deltaz = cell_size / lenz;

	int out = -1;
	float out_dist = tmax + constant::epsilon;

	while(true) {
		int node_id = nodeAt(pos);
		const Node &node = m_nodes[node_id];

		if(flagTest(node.obj_flags, flags) && intersection(ray, node.bbox) < out_dist) {
			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, ignored_id, flags);

			for(int n = 0; n < count; n++) {
				float dist = intersection(ray, objects[n]->bbox);
				if(dist < out_dist) {
					out_dist = dist;
					out = objects[n] - &m_objects[0];
				}
			}	
			
			if(node.is_dirty)
				updateNode(node_id);
		}

		if(tx <= tz || dz == 0) {
			if(pos.x == end.x)
				break;
			tx += deltax;
			pos.x += dx;
		}
		else {
			if(pos.y == end.y)
				break;
			tz += deltaz;
			pos.y += dz;
		}
		float ray_pos = tmin + max((tx - deltax) * lenx, (tz - deltaz) * lenz);
		if(ray_pos >= out_dist)
			break;
	}

	return make_pair(out, out_dist);
}
示例#7
0
void Grid::traceCoherent(const vector<Segment> &segments, vector<pair<int, float>> &out, int ignored_id, int flags) const {
	out.resize(segments.size(), make_pair(-1, constant::inf));

	if(segments.empty())
		return;

	int2 start, end; {
		float3 pmin(constant::inf, constant::inf, constant::inf);
		float3 pmax(-constant::inf, -constant::inf, -constant::inf);

		for(int s = 0; s < (int)segments.size(); s++) {
			const Segment &segment = segments[s];
			float tmin = max(0.0f, intersection(segment, m_bounding_box));
			float tmax = min(segment.length(), -intersection(-segment, m_bounding_box));

			float3 p1 = segment.at(tmin), p2 = segment.at(tmax);
			pmin = min(pmin, min(p1, p2));
			pmax = max(pmax, max(p1, p2));
		}

		start = worldToGrid((int2)pmin.xz());
		end = worldToGrid((int2)pmax.xz());
		start = max(start, int2(0, 0));
		end = min(end, int2(m_size.x - 1, m_size.y - 1));
	}

	float max_dist = -constant::inf;	
	Interval idir[3], origin[3]; {
		const Segment &first = segments.front();
		idir  [0] = first.invDir().x; idir  [1] = first.invDir().y; idir  [2] = first.invDir().z;
		origin[0] = first.origin().x; origin[1] = first.origin().y; origin[2] = first.origin().z;

		for(int s = 1; s < (int)segments.size(); s++) {
			const Segment &segment = segments[s];
			float tidir[3] = { segment.invDir().x, segment.invDir().y, segment.invDir().z };
			float torigin[3] = { segment.origin().x, segment.origin().y, segment.origin().z };

			max_dist = max(max_dist, segment.length());
			for(int i = 0; i < 3; i++) {
				idir  [i] = Interval(min(idir  [i].min, tidir  [i]), max(idir  [i].max, tidir  [i]));
				origin[i] = Interval(min(origin[i].min, torigin[i]), max(origin[i].max, torigin[i]));
			}
		}
	}

	for(int x = start.x; x <= end.x; x++) for(int z = start.y; z <= end.y; z++) {
		int node_id = nodeAt(int2(x, z));
		const Node &node = m_nodes[node_id];

		if(flagTest(node.obj_flags, flags) && intersection(idir, origin, node.bbox) < max_dist) {
			const Object *objects[node.size];
			int count = extractObjects(node_id, objects, ignored_id, flags);

			for(int n = 0; n < count; n++) {
				if(intersection(idir, origin, objects[n]->bbox) < max_dist) {
					for(int s = 0; s < (int)segments.size(); s++) {
						const Segment &segment = segments[s];
						float dist = intersection(segment, objects[n]->bbox);
						if(dist < out[s].second) {
							out[s].second = dist;
							out[s].first = objects[n] - &m_objects[0];
						}
					}
				}
			}
			
			if(node.is_dirty)
				updateNode(node_id);
		}
	}
}