/*! Subdivides the mesh uniformly one step
*/
void LoopSubdivisionMesh::Subdivide()
{
  // Create new mesh and copy all the attributes
  HalfEdgeMesh subDivMesh;
  subDivMesh.SetTransform(GetTransform());
  subDivMesh.SetName(GetName());
  subDivMesh.SetColorMap(GetColorMap());
  subDivMesh.SetWireframe(GetWireframe());
  subDivMesh.SetShowNormals(GetShowNormals());
  subDivMesh.SetOpacity(GetOpacity());
  if (IsHovering()) subDivMesh.Hover();
  if (IsSelected()) subDivMesh.Select();
  subDivMesh.mMinCMap = mMinCMap;
  subDivMesh.mMaxCMap = mMaxCMap;
  subDivMesh.mAutoMinMax = mAutoMinMax;


  // loop over each face and create 4 new ones
  for (unsigned int i=0; i<mFaces.size(); i++){
    // subdivide face
    std::vector< std::vector<Vector3<float> > > faces = Subdivide(i);

    // add new faces to subDivMesh
    for(unsigned int j=0; j<faces.size(); j++){
      subDivMesh.AddFace(faces.at(j));
    }
  }

  // Assigns the new mesh
  *this = LoopSubdivisionMesh(subDivMesh, ++mNumSubDivs);
  Update();
}
Ejemplo n.º 2
0
	//TODO: drive this with a generic VBO descriptor to avoid special case drawing like these particles
	static void DrawParticles( const DrawParticlesCommand &cmd ) {
		if ( !cmd.material ) {
			console.Print( PrintLevel::Developer, "%s with invalid material\n",
				XS_FUNCTION
			);
			return;
		}

		cmd.material->Bind();

		bool setWireframe = false;
		bool previousWireframe = false;
		if ( r_wireframe->GetBool() || (cmd.material->flags & MF_WIREFRAME) ) {
			setWireframe = true;
			previousWireframe = GetWireframe();
			ToggleWireframe( true );
		}

		if ( cmd.vbo ) {
			cmd.vbo->Bind();

			// position4, uv2, colour4
			EnableVertexAttribs( VERTEX_ATTRIB_0 | VERTEX_ATTRIB_1 | VERTEX_ATTRIB_2 );

			// calculate stride
			GLsizei stride = sizeof(vector4) + sizeof(vector2) + sizeof(vector4);

			// set the attribute pointers
			size_t offset = 0u;
			glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
			offset += sizeof(vector4);

			glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
			offset += sizeof(vector2);

			glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
			offset += sizeof(vector4);
		}

		if ( 1 ) {
			cmd.ibo->Bind();
			GLint size = 0;
			glGetBufferParameteriv( GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size );
			glDrawElements( GL_TRIANGLES, size / sizeof(uint32_t), GL_UNSIGNED_INT, 0 );
		}
		else {
			glDrawArrays( GL_TRIANGLES, 0, cmd.count );
		}

		// clean up state
		if ( setWireframe ) {
			ToggleWireframe( previousWireframe );
		}
	}
/*! Subdivides the mesh one step, depending on subdividability
*/
void AdaptiveLoopSubdivisionMesh::Subdivide()
{
  // Create new mesh and copy all the attributes
  HalfEdgeMesh subDivMesh;
  subDivMesh.SetTransform(GetTransform());
  subDivMesh.SetName(GetName());
  subDivMesh.SetColorMap(GetColorMap());
  subDivMesh.SetWireframe(GetWireframe());
  subDivMesh.SetShowNormals(GetShowNormals());
  subDivMesh.SetOpacity(GetOpacity());
  if (IsHovering()) subDivMesh.Hover();
  if (IsSelected()) subDivMesh.Select();
  subDivMesh.mMinCMap = mMinCMap;
  subDivMesh.mMaxCMap = mMaxCMap;
  subDivMesh.mAutoMinMax = mAutoMinMax;


  // loop over each face and create new ones
  for(unsigned int i=0; i<GetNumFaces(); i++){

    // find neighbor faces
    unsigned int f1, f2, f3;
    EdgeIterator eit = GetEdgeIterator( f(i).edge );
    f1 = eit.Pair().GetEdgeFaceIndex(); eit.Pair();
    f2 = eit.Next().Pair().GetEdgeFaceIndex(); eit.Pair();
    f3 = eit.Next().Pair().GetEdgeFaceIndex();

    unsigned int numNotSubdividable = !Subdividable(f1) + !Subdividable(f2) + !Subdividable(f3);

    // Do not subdivide if "self" is not subdividable
    if(!Subdividable(i)){
      numNotSubdividable = 3;
    }

    std::vector< std::vector <Vector3<float> > > faces;
    switch(numNotSubdividable){
    case 0:
      // normal subdivision (from LoopSubdivisionMesh)
      faces = LoopSubdivisionMesh::Subdivide(i);
      break;
    case 1:
      // special case 1
      faces = Subdivide1(i);
      break;
    case 2:
      // special case 2
      faces = Subdivide2(i);
      break;
    case 3:
      // trivial case, no subdivision, same as if subdividable(fi) == false
      faces = Subdivide3(i);
      break;
    }

    // add the faces (if any) to subDivMesh
    for(unsigned int j=0; j<faces.size(); j++){
      subDivMesh.AddFace(faces.at(j));
    }
  }

  // Assign the new mesh
  *this = AdaptiveLoopSubdivisionMesh(subDivMesh, ++mNumSubDivs);
  Update();
}
Ejemplo n.º 4
0
	static void DrawMesh( const Mesh *mesh ) {
		SDL_assert( mesh->material && "DrawMesh with invalid material" );

		bool setWireframe = false;
		bool previousWireframe = false;
		if ( r_wireframe->GetBool() || (mesh->material->flags & MF_WIREFRAME) ) {
			setWireframe = true;
			previousWireframe = GetWireframe();
			ToggleWireframe( true );
		}

		// bind the vertex/normal/uv buffers
		if ( mesh->vertexBuffer ) {
			const bool hasVerts = !mesh->vertices.empty();
			const bool hasNormals = !mesh->normals.empty();
			const bool hasUVs = !mesh->UVs.empty();

			mesh->vertexBuffer->Bind();

			uint32_t vertexAttribs = 0u;
			if ( hasVerts ) {
				vertexAttribs |= VERTEX_ATTRIB_0;
			}
			if ( hasNormals ) {
				vertexAttribs |= VERTEX_ATTRIB_1;
			}
			if ( hasUVs ) {
				vertexAttribs |= VERTEX_ATTRIB_2;
			}

			EnableVertexAttribs( vertexAttribs );

			// calculate stride
			GLsizei stride = 0;
			if ( hasVerts ) {
				stride += sizeof(vector3);
			}
			if ( hasNormals ) {
				stride += sizeof(vector3);
			}
			if ( hasUVs ) {
				stride += sizeof(vector2);
			}

			// set the attribute pointers
			size_t offset = 0u;
			if ( hasVerts ) {
				glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
				offset += sizeof(vector3);
			}

			if ( hasNormals ) {
				glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
				offset += sizeof(vector3);
			}

			if ( hasUVs ) {
				glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) );
				offset += sizeof(vector2);
			}
		}

		// issue the draw command
		//FIXME: index buffer is all kinds of wrong when using glDrawElements
		if ( 0 ) {//mesh->indexBuffer ) {
			mesh->indexBuffer->Bind();
			GLint size = 0;
			glGetBufferParameteriv( GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size );
			glDrawElements( GL_TRIANGLES, size / sizeof(uint32_t), GL_UNSIGNED_INT, 0 );
		}
		else {
			glDrawArrays( GL_TRIANGLES, 0, mesh->indices.size() );
		}

		// clean up state
		if ( setWireframe ) {
			ToggleWireframe( previousWireframe );
		}
	}