Example #1
0
void collectFaceVertices(Mesh& m) {
  for (int i = 0; i < m.getNumFaces(); ++i) {
    Mesh::Face f = m.getFace(i);
    vector<Cvec3> vertices;
    for (int j = 0; j < f.getNumVertices(); ++j) {
      vertices.push_back(f.getVertex(j).getPosition());
    }
    m.setNewFaceVertex(f, getFaceVertex(vertices));
  }
}
Example #2
0
static void applySubdivs(Mesh &mesh, int subdivLevel) {
  for (int i = 0; i < subdivLevel; i++) {
    // subdivide faces
    for (int j = 0, n = mesh.getNumFaces(); j < n; j++) {
      Mesh::Face face = mesh.getFace(j);
      int verticesAroundFace = face.getNumVertices();
      Cvec3 vertexSum = Cvec3();
      for (int k = 0; k < verticesAroundFace; k++) {
        vertexSum += face.getVertex(k).getPosition();
      }
      vertexSum = vertexSum * (1.0 / verticesAroundFace); 
      mesh.setNewFaceVertex(face, vertexSum);
    }

    // subdivide edges
    for (int j = 0, n = mesh.getNumEdges(); j < n; j++) {
      Mesh::Edge edge = mesh.getEdge(j);
      Cvec3 vertexSum = (edge.getVertex(0).getPosition() +
        edge.getVertex(1).getPosition() +
        mesh.getNewFaceVertex(edge.getFace(0)) +
        mesh.getNewFaceVertex(edge.getFace(1))) * 0.25;
      mesh.setNewEdgeVertex(edge, vertexSum); 
    }

    // subdivide vertices
    for (int j = 0, n = mesh.getNumVertices(); j < n; j++) {
      Mesh::Vertex v = mesh.getVertex(j);
      int numOfVertices = 0;
      
      Mesh::VertexIterator vertexIter(v.getIterator()), iterOrigin(vertexIter);
      Cvec3 accumVertices = Cvec3();
      Cvec3 accumFaceVertices = Cvec3();

      do {
        accumVertices += vertexIter.getVertex().getPosition();
        accumFaceVertices += mesh.getNewFaceVertex(vertexIter.getFace());
        
        numOfVertices++;
      } while (++vertexIter != iterOrigin);
      
      double factor = 1.0 / (numOfVertices * numOfVertices);

      Cvec3 vertexVertex = 
        v.getPosition() * ((numOfVertices - 2.0) / numOfVertices) +
        accumVertices * factor +
        accumFaceVertices * factor; 
      mesh.setNewVertexVertex(mesh.getVertex(j), vertexVertex);
    }
    
    // subdivide for each level of subdivision we need 
    mesh.subdivide();
  }
}
Example #3
0
static void simpleShadeCube(Mesh& mesh) {
  Cvec3 normal = Cvec3(0, 1, 0);
  for (int i = 0; i < mesh.getNumFaces(); ++i) {
    const Mesh::Face f = mesh.getFace(i);
    Cvec3 facenorm = f.getNormal();

    for (int j = 0; j < f.getNumVertices(); ++j) {
      const Mesh::Vertex v = f.getVertex(j);
      v.setNormal(facenorm);
    }
  }
}
Example #4
0
bool Mesh::verify_same_direction(Mesh::Face current_face, Point3D vertices[],
    Point3D& point, Vector3D& normal)
{
  bool is_same_direction = false;
  // Make sure the intersect face is pointing to the same direction
  for (unsigned int i = 0; i < current_face.size(); i++) {
    is_same_direction =
        ((vertices[(i + 1) % current_face.size()] - vertices[i]).cross(
            point - vertices[i]).dot(normal)) >= 0;
    if (!is_same_direction) {
      break;
    }
  }
  return is_same_direction;
}
Example #5
0
static void initCubeMesh() {
  if (!meshLoaded) {
    cubeMesh.load("./cube.mesh");
    meshLoaded = true;
  }

  // set normals
  shadeCube(cubeMesh);

  // collect vertices from each face and map quads to triangles
  vector<VertexPN> verts;
  for (int i = 0; i < cubeMesh.getNumFaces(); ++i) {
    const Mesh::Face f = cubeMesh.getFace(i);
    Cvec3 pos;
    Cvec3 normal;

    if (g_flat)
      normal = f.getNormal();

    for (int j = 0; j < f.getNumVertices(); ++j) {
      const Mesh::Vertex v = f.getVertex(j);
      pos = v.getPosition();

      if (!g_flat)
        normal = v.getNormal();

      verts.push_back(VertexPN(pos, normal));
      if (j == 2) {
        verts.push_back(VertexPN(pos, normal));
      }
    }
    const Mesh::Vertex v = f.getVertex(0);
    pos = v.getPosition();

    if (!g_flat)
      normal = v.getNormal();

    verts.push_back(VertexPN(pos, normal));
  }

  // add vertices to cube geometry
  int numVertices = verts.size();
  if (!g_cubeGeometryPN) {
    g_cubeGeometryPN.reset(new SimpleGeometryPN());
  }
  g_cubeGeometryPN->upload(&verts[0], numVertices);
}
Example #6
0
static vector<VertexPN> getMeshVertices(Mesh &mesh) {
  vector<VertexPN> vertices;

  for (int i = 0, n = mesh.getNumFaces(); i < n; i++) {
    Mesh::Face face = mesh.getFace(i);
    
    Cvec3 normals[3];
    for (int j = 1; j < face.getNumVertices() - 1; j++) {

      if (g_smoothShadeOn) {
        normals[0] = face.getVertex(0).getNormal();
        normals[1] = face.getVertex(j).getNormal();
        normals[2] = face.getVertex(j+1).getNormal();
      } else {
        normals[0] = normals[1] = normals[2] = face.getNormal();
      }

      vertices.push_back(VertexPN(face.getVertex(0).getPosition(), normals[0]));
      vertices.push_back(VertexPN(face.getVertex(j).getPosition(), normals[1]));
      vertices.push_back(VertexPN(face.getVertex(j+1).getPosition(), normals[2]));

    }
  }
  return vertices;
}
Example #7
0
static void updateShellGeometry() {
  float xs[] = {0, g_hairyness, 0};
  float ys[] = {0, 0, g_hairyness};


  vector<Cvec3> prevPos;
  prevPos.resize(g_bunnyMesh.getNumFaces() * 3);

  for (int level = 0; level < g_numShells; ++level) {
    int counter = 0;
    vector<VertexPNX> verts;
    for (int i = 0; i < g_bunnyMesh.getNumFaces(); ++i) {
      const Mesh::Face f = g_bunnyMesh.getFace(i);
      for (int j = 0; j < f.getNumVertices(); ++j) {
        const Mesh::Vertex v = f.getVertex(j);
        int index = v.getIndex();
        Cvec3 pos = v.getPosition();
        Cvec3 normal = v.getNormal();
        Cvec2 c = Cvec2(xs[j], ys[j]);

        Cvec3 n = normal * g_furHeight / g_numShells;
        Cvec3 s = pos + (n * g_numShells);
        Cvec3 t = world2bunny(g_tipPos[index]);
        Cvec3 d = (t - s) / ((g_numShells + 1) * g_numShells / 2);
        /* Cvec3 d = (world2bunny(g_tipPos[index]) - (normal * g_furHeight)) / (g_numShells - 1); */

        if (level == 0) {
          prevPos[counter] = pos;
          verts.push_back(VertexPNX(pos, n, c));
        }
        else {
          Cvec3 new_position = prevPos[counter] + n + (d * level);
          verts.push_back(VertexPNX(new_position, new_position - prevPos[counter], c));
          prevPos[counter] = new_position;
        }
        ++counter;
      }
    }
    int numVertices = verts.size();
    g_bunnyShellGeometries[level]->upload(&verts[0], numVertices);
    verts.clear();
  }
}
Example #8
0
bool Mesh::faceIntersection(
    const Ray& ray, HitRecord* hitRecord, const Mesh::Face& face) {
  // Get a point on the plane
  Vector3D norm;
  double t;
  {
    const auto& p0 = m_verts[face[0]];
    const auto& p1 = m_verts[face[1]];
    const auto& p2 = m_verts[face[face.size()-1]];
    norm = (p1 - p0).cross(p2 - p0);
    auto rayNorm = ray.dir.dot(norm);

    // Parallel
    if (isZero(rayNorm)) return false;

    t = (p0 - ray.start).dot(norm) / rayNorm;
    // No intersection
    if (t < 0 || isZero(t)) {
      return false;
    }
  }

  // Intersection point
  auto planePt = ray.at(t);
  // Now check if planePt is "left" of everything
  for (size_t i = 0; i < face.size(); ++i) {
    // Go over points in order
    const auto& p1 = m_verts[face[i]];
    const auto& p2 = m_verts[face[(i + 1) % face.size()]];
    // from p1 to p2
    const auto side = p2 - p1;
    // cross from p1 to plane pt and dot against normal
    auto k = norm.dot(side.cross(planePt - p1));
    if (!isZero(k) && k < 0) {
      // Zero means on the side; negative means opposite dir from norm
      return false;
    }
  }

  // Update if this is a better t value
  return hitRecord->update(norm, planePt, t);
}
Example #9
0
static void initBunnyMeshes() {
  g_bunnyMesh.load("bunny.mesh");

  // TODO: Init the per vertex normal of g_bunnyMesh, using codes from asst7
  // ...
  shadeCube(g_bunnyMesh);
  // cout << "Finished shading bunny" << endl;
  // TODO: Initialize g_bunnyGeometry from g_bunnyMesh, similar to
  vector<VertexPN> verts;
  for (int i = 0; i < g_bunnyMesh.getNumFaces(); ++i) {
    const Mesh::Face f = g_bunnyMesh.getFace(i);
    Cvec3 pos;
    Cvec3 normal;

    if (g_flat)
      normal = f.getNormal();

    for (int j = 0; j < f.getNumVertices(); ++j) {
      const Mesh::Vertex v = f.getVertex(j);
      pos = v.getPosition();

      if (!g_flat)
        normal = v.getNormal();

      verts.push_back(VertexPN(pos, normal));
    }
  }

  // add vertices to bunny geometry
  int numVertices = verts.size();

  g_bunnyGeometry.reset(new SimpleGeometryPN());
  g_bunnyGeometry->upload(&verts[0], numVertices);

  // Now allocate array of SimpleGeometryPNX to for shells, one per layer
  g_bunnyShellGeometries.resize(g_numShells);
  for (int i = 0; i < g_numShells; ++i) {
    g_bunnyShellGeometries[i].reset(new SimpleGeometryPNX());
  }
}
Example #10
0
static void shadeCube(Mesh& mesh) {
  Cvec3 normal = Cvec3(0, 0, 0);
  for (int i = 0; i < mesh.getNumVertices(); ++i) {
    mesh.getVertex(i).setNormal(normal);
  }

  for (int i = 0; i < mesh.getNumFaces(); ++i) {
    const Mesh::Face f = mesh.getFace(i);
    Cvec3 facenorm = f.getNormal();

    for (int j = 0; j < f.getNumVertices(); ++j) {
      const Mesh::Vertex v = f.getVertex(j);
      v.setNormal(facenorm + v.getNormal());
    }
  }

  for (int i = 0; i < mesh.getNumVertices(); ++i) {
    const Mesh::Vertex v = mesh.getVertex(i);
    if (norm2(v.getNormal()) > .001) {
          v.setNormal(normalize(v.getNormal()));
    }
  }
}
Example #11
0
static void loadMeshGeometry(Mesh& m, GeometryPX& g) {
	vector<GLfloat> pos, tex;
	for (int i = 0; i < m.getNumFaces(); ++i) {
		const Mesh::Face f = m.getFace(i);
		for (int j = 0; j < f.getNumVertices(); ++j) {
			const Mesh::Vertex v = f.getVertex(j);
			pos.push_back((GLfloat)(v.getPosition()[0]));
			pos.push_back((GLfloat)(v.getPosition()[1]));
			tex.push_back((GLfloat)v.getTexCoords()[0]);
			tex.push_back((GLfloat)v.getTexCoords()[1]);
		}
	}

	const unsigned int size = pos.size() * sizeof(GLfloat);
	glBindBuffer(GL_ARRAY_BUFFER, g.posVbo);
	glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, size, &pos[0]);
	checkGlErrors();

	glBindBuffer(GL_ARRAY_BUFFER, g.texVbo);
	glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, size, &tex[0]);
	checkGlErrors();
}
Example #12
0
static void animateCube(int ms) {
  float t = (float) ms / (float) g_msBetweenKeyFrames;

  // scale all vertices in cube
  for (int i = 0; i < cubeMesh.getNumVertices(); ++i) {
    const Mesh::Vertex v = cubeMesh.getVertex(i);
    Cvec3 pos = v.getPosition();
    double factor = (1 + (float(g_div_level)/10)) * ((-1 * sin((double) (g_horiz_scale * ms) / (1000 * (vertex_speeds[i] + .5))) + 1) / 2 + .5);
    pos[0] = vertex_signs[i][0] * (factor / sqrt(3));
    pos[1] = vertex_signs[i][1] * (factor / sqrt(3));
    pos[2] = vertex_signs[i][2] * (factor / sqrt(3));
    v.setPosition(pos);

  }

  // copy mesh to temporary mesh for rendering
  Mesh renderMesh = cubeMesh;

  // subdivision
  for (int i = 0; i < g_div_level; ++i) {
    collectFaceVertices(renderMesh);
    collectEdgeVertices(renderMesh);
    collectVertexVertices(renderMesh);
    renderMesh.subdivide();

  }

  // set normals
  shadeCube(renderMesh);

  // collect vertices for each face
  vector<VertexPN> verts;
  int q = 0;
  for (int i = 0; i < renderMesh.getNumFaces(); ++i) {
    const Mesh::Face f = renderMesh.getFace(i);
    Cvec3 pos;
    Cvec3 normal;
    for (int j = 0; j < f.getNumVertices(); ++j) {
      const Mesh::Vertex v = f.getVertex(j);
      pos = v.getPosition();

      if (!g_flat)
        normal = v.getNormal();
      else
        normal = f.getNormal();

      verts.push_back(VertexPN(pos, normal));
      if (j == 2) {
        verts.push_back(VertexPN(pos, normal));
      }
    }
    const Mesh::Vertex v = f.getVertex(0);
    pos = v.getPosition();
    if (!g_flat)
      normal = v.getNormal();
    else
      normal = f.getNormal();
    verts.push_back(VertexPN(pos, normal));
  }

  // dump into geometry
  int numVertices = verts.size();
  g_cubeGeometryPN->upload(&verts[0], numVertices);
  glutPostRedisplay();
  glutTimerFunc(1000/g_animateFramesPerSecond,
      animateCube,
      ms + 1000/g_animateFramesPerSecond);
}