Exemple #1
0
void Gizmo::transform(ComponentIndex camera, int x, int y, int relx, int rely, bool use_step)
{
	if (!m_is_transforming) return;

	if (m_mode == Mode::ROTATE)
	{
		rotate(relx, rely, use_step);
	}
	else
	{
		Vec3 intersection = getMousePlaneIntersection(camera, x, y);
		Vec3 delta = intersection - m_transform_point;
		if (!use_step || delta.length() > float(getStep()))
		{
			if (use_step) delta = delta.normalized() * float(getStep());

			Array<Vec3> new_positions(m_editor.getAllocator());
			for (int i = 0, ci = m_editor.getSelectedEntities().size(); i < ci; ++i)
			{
				Vec3 pos = m_editor.getUniverse()->getPosition(m_editor.getSelectedEntities()[i]);
				pos += delta;
				new_positions.push(pos);
			}
			m_editor.setEntitiesPositions(&m_editor.getSelectedEntities()[0],
				&new_positions[0],
				new_positions.size());
			if (m_is_autosnap_down) m_editor.snapDown();

			m_transform_point = intersection;
		}
	}
}
void		player_expulse(t_server *server, t_client *client)
{
  char		*str;

  asprintf(&str, "pex #%d\n", client->socket);
  broadcast(server->clients, str, FD_GRAPHIC);
  free(str);

  new_positions(server, server->clients);
}
Exemple #3
0
	virtual Optimization::SimulatedAnnealing::state_ptr get_random_neighbor() {
		int num_queens = _positions.size();
		std::vector<int> new_positions(num_queens);
		
		std::copy(_positions.begin(), _positions.end(), new_positions.begin());
		
		int r1 = static_cast<int>(static_cast<float>(num_queens) * static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
		int r2 = static_cast<int>(static_cast<float>(num_queens) * static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
		
		int t = new_positions[r1];
		new_positions[r1] = new_positions[r2];
		new_positions[r2] = t;
		
		return Optimization::SimulatedAnnealing::state_ptr(new BoardState(new_positions));
	}
Exemple #4
0
void Gizmo::rotate(int relx, int rely, bool use_step)
{
	Universe* universe = m_editor.getUniverse();
	Array<Vec3> new_positions(m_editor.getAllocator());
	Array<Quat> new_rotations(m_editor.getAllocator());
	for (int i = 0, c = m_editor.getSelectedEntities().size(); i < c; ++i)
	{
		Vec3 pos = universe->getPosition(m_editor.getSelectedEntities()[i]);
		Matrix gizmo_mtx;
		getMatrix(gizmo_mtx);
		Vec3 axis;
		switch (m_transform_axis)
		{
			case Axis::X: axis = gizmo_mtx.getXVector(); break;
			case Axis::Y: axis = gizmo_mtx.getYVector(); break;
			case Axis::Z: axis = gizmo_mtx.getZVector(); break;
		}
		float angle = computeRotateAngle(relx, rely, use_step);

		Quat old_rot = universe->getRotation(m_editor.getSelectedEntities()[i]);
		Quat new_rot = old_rot * Quat(axis, angle);
		new_rot.normalize();
		new_rotations.push(new_rot);

		Vec3 pdif = gizmo_mtx.getTranslation() - pos;

		old_rot.conjugate();
		pos = -pdif;
		pos = new_rot * (old_rot * pos);
		pos += gizmo_mtx.getTranslation();

		new_positions.push(pos);
	}
	m_editor.setEntitiesPositionsAndRotations(&m_editor.getSelectedEntities()[0],
		&new_positions[0],
		&new_rotations[0],
		new_positions.size());
}
void MeshWithConnectivity::LoopSubdivision() {
	// generate new (odd) vertices

	// visited edge -> vertex position information
	// Note that this is different from the one in computeConnectivity()
	typedef std::map<std::pair<int, int>, int> edgemap_t;
	edgemap_t new_vertices;

	// The new data must be doublebuffered or otherwise some of the calculations below would
	// not read the original positions but the newly changed ones, which is slightly wrong.
	std::vector<Vec3f> new_positions(positions.size());
	std::vector<Vec3f> new_normals(normals.size());
	std::vector<Vec3f> new_colors(colors.size());

	for (size_t i = 0; i < indices.size(); ++i)
		for (int j = 0; j < 3; ++j) {
			int v0 = indices[i][j];
			int v1 = indices[i][(j+1)%3];

			// Map the edge endpoint indices to new vertex index.
			// We use min and max because the edge direction does not matter when we finally
			// rebuild the new faces (R3); this is how we always get unique indices for the map.
			auto edge = std::make_pair(min(v0, v1), max(v0, v1));

			// With naive iteration, we would find each edge twice, because each is part of two triangles
			// (if the mesh does not have any holes/empty borders). Thus, we keep track of the already
			// visited edges in the new_vertices map. That requires the small R3 task below in the 'if' block.
			if (new_vertices.find(edge) == new_vertices.end()) {
				// YOUR CODE HERE (R4): compute the position for odd (= new) vertex.
				Vec3f pos, col, norm;
				int leftvertex, rightvertex;
				// You will need to use the neighbor information to find the correct vertices.
				// Be careful with indexing!
				// No need to worry about boundaries, though (except for the extra credit!).

				// Then, use the correct weights for each four corner vertex.
				// This default implementation just puts the new vertex at the edge midpoint.
				if (j == 0)
					leftvertex = indices[i][2];
				else if (j == 1)
					leftvertex = indices[i][0];
				else
					leftvertex = indices[i][1];
				Vec3i neigh = neighborTris[i];
				bool found = false;
				for (int k = 0; k < 3; k++)
				{
					int kms = neigh[k];

					if (kms == -1)
						continue;

					int x = indices[kms][0], y= indices[kms][1], z = indices[kms][2];
					if ((indices[kms][0] == v0 || indices[kms][1] == v0 || indices[kms][2] == v0) && (indices[kms][0] == v1 || indices[kms][1] == v1 || indices[kms][2] == v1))
					{
						if ((x == v0 && y == v1) || (x == v1 && y == v0))
							rightvertex = z;
						else if ((y == v0 && z == v1) || (z == v0 && y == v1))
							rightvertex = x;
						else
							rightvertex = y;
						found = true;
						break;
					}
				}
				if (found){
					pos = ((3.0f * (positions[v0] + positions[v1])) + (positions[leftvertex] + positions[rightvertex])) / 8.0f;
					col = ((3.0f * (colors[v0] + colors[v1])) + (colors[leftvertex] + colors[rightvertex])) / 8.0f;
					norm = ((3.0f * (normals[v0] + normals[v1])) + (normals[leftvertex] + normals[rightvertex])) / 8.0f;
				}

				else {
					pos = 0.5f * (positions[v0] + positions[v1]);
					col = 0.5f * (colors[v0] + colors[v1]);
					norm = 0.5f * (normals[v0] + normals[v1]);
				}
				new_positions.push_back(pos);
				new_colors.push_back(col);
				new_normals.push_back(norm);

				// YOUR CODE HERE (R3):
				// Map the edge to the correct vertex index.
				new_vertices[edge] = new_positions.size() - 1;
				// This is just one line! Use new_vertices and the index of the just added position.
			}
		}
		// compute positions for even (old) vertices
		std::vector<bool> vertexComputed(new_positions.size(), false);

		for (int i = 0; i < (int)indices.size(); ++i) {
			for (int j = 0; j < 3; ++j) {
				int v0 = indices[i][j];

				// don't redo if this one is already done
				if (vertexComputed[v0])
					continue;

				vertexComputed[v0] = true;

				Vec3f pos, col, norm;
				std::vector<int> neighbors;
				// YOUR CODE HERE (R5): reposition the old vertices

				// This default implementation just passes the data through unchanged.
				// You need to replace these three lines with the loop over the 1-ring
				// around vertex v0, and compute the new position as a weighted average
				// of the other vertices as described in the handout.
				for (int k = 0; k < indices.size(); k++){
					for (int l = 0; l < 3; l++){
						if (indices[k][l] == v0){
							neighbors.push_back(indices[k][(l + 1) % 3]);
							neighbors.push_back(indices[k][(l + 2) % 3]);
						}
					}
				}
				sort(neighbors.begin(), neighbors.end());
				neighbors.erase(std::unique(neighbors.begin(),neighbors.end()), neighbors.end());

				int n = neighbors.size();
				float b;
				if (n>3)
					b = 3.0f / (8.0f * n);
				else if (n == 3)
					b = 3.0f / 16.0f;
				else
					b = 0.0f;
				Vec3f rightsum1, rightsum2, rightsum3;
				for (int k = 0; k < neighbors.size(); k++){
					rightsum1 += positions[neighbors[k]];
					rightsum2 += colors[neighbors[k]];
					rightsum3 += normals[neighbors[k]];
				}
				rightsum1 *= (float)b;
				rightsum2 *= (float)b;
				rightsum3 *= (float)b;
				float ks = 1.0f - (float)n*(float)b;
				rightsum1 += ks * positions[v0];
				rightsum2 += ks * colors[v0];
				rightsum3 += ks * normals[v0];
				pos = rightsum1;
				col = rightsum2;
				norm = rightsum3;

				new_positions[v0] = pos;
				new_colors[v0] = col;
				new_normals[v0] = norm;
			}
		}
		// and then, finally, regenerate topology
		// every triangle turns into four new ones
		std::vector<Vec3i> new_indices;
		new_indices.reserve(indices.size()*4);
		for (size_t i = 0; i < indices.size(); ++i) {
			Vec3i even = indices[i]; // start vertices of e_0, e_1, e_2

			// YOUR CODE HERE (R3):
			// fill in X and Y (it's the same for both)
			auto edge_a = std::make_pair(min(even.x, even.y), max(even.x, even.y));
			auto edge_b = std::make_pair(min(even.z, even.y), max(even.z, even.y));
			auto edge_c = std::make_pair(min(even.x, even.z), max(even.x, even.z));

			// The edges edge_a, edge_b and edge_c now define the vertex indices via new_vertices.
			// (The mapping is done in the loop above.)
			// The indices define the smaller triangle inside the indices defined by "even", in order.
			// Read the vertex indices out of new_vertices to build the small triangle "odd"
			int a, b, c;
			a = new_vertices[edge_a];
			b = new_vertices[edge_b];
			c = new_vertices[edge_c];
			// Vec3i odd = ...
			new_indices.push_back(Vec3i(a,b,c));
			new_indices.push_back(Vec3i(a, b, even[1]));
			new_indices.push_back(Vec3i(a,c, even[0]));
			new_indices.push_back(Vec3i(b, c, even[2]));
			// Then, construct the four smaller triangles from the surrounding big triangle  "even"
			// and the inner one, "odd". Push them to "new_indices".

			// NOTE: REMOVE the following line after you're done with the new triangles.
			// This just keeps the mesh intact and serves as an example on how to add new triangles.
			//new_indices.push_back( Vec3i( even[0], even[1], even[2] ) );
		}

		// ADD THESE LINES when R3 is finished. Replace the originals with the repositioned data.
		indices = std::move(new_indices);
		positions = std::move(new_positions);
		normals = std::move(new_normals);
		colors = std::move(new_colors);
		neighborTris.size();
}