void TriangulateTraverser::handlePrimitive( Primitive * p )
      {
        if( !optimizationAllowed( p->getSharedPtr<Primitive>() ) )
        {
          return;
        }

        DP_ASSERT( !m_triangulatedPrimitive );
        PrimitiveType primitiveType = p->getPrimitiveType();
        if ( ( primitiveType == PrimitiveType::QUAD_STRIP ) || ( primitiveType == PrimitiveType::QUADS ) )
        {
          // create a new Primitive QuadStrip -> TriStrip or Quads -> Tris
          m_triangulatedPrimitive = Primitive::create( primitiveType == PrimitiveType::QUAD_STRIP ? PrimitiveType::TRIANGLE_STRIP : PrimitiveType::TRIANGLES );

          m_triangulatedPrimitive->setName( p->getName() );
          m_triangulatedPrimitive->setAnnotation( p->getAnnotation() );
          m_triangulatedPrimitive->setHints( p->getHints() );
          m_triangulatedPrimitive->setTraversalMask( p->getTraversalMask() );
          m_triangulatedPrimitive->setInstanceCount( p->getInstanceCount() );
          m_triangulatedPrimitive->setElementRange( p->getElementOffset(), p->getElementCount() );
          m_triangulatedPrimitive->setInstanceCount( p->getInstanceCount() );
          m_triangulatedPrimitive->setVertexAttributeSet( p->getVertexAttributeSet() );
          m_triangulatedPrimitive->setIndexSet( p->getIndexSet() );

          // from quad strip to tri strip is just copying the Primitive into a new tri strip; that is, we're alread done
          // otherwise...
          if ( primitiveType == PrimitiveType::QUADS )
          {
            m_triangulatedPrimitive->makeIndexed();
            vector<unsigned int> newIndices;
            convertQuadsToTriangles( IndexSet::ConstIterator<unsigned int>( m_triangulatedPrimitive->getIndexSet(), m_triangulatedPrimitive->getElementOffset() )
                                   , m_triangulatedPrimitive->getElementCount(), m_triangulatedPrimitive->getVertexAttributeSet(), newIndices
                                   , m_triangulatedPrimitive->getIndexSet()->getPrimitiveRestartIndex() );
            IndexSetSharedPtr triangulatedIndexSet = std::static_pointer_cast<IndexSet>(m_triangulatedPrimitive->getIndexSet()->clone());
            triangulatedIndexSet->setData( &newIndices[0], dp::checked_cast<unsigned int>(newIndices.size()) );
            triangulatedIndexSet->setPrimitiveRestartIndex( ~0 );
          }
        }
      }
Beispiel #2
0
void Geometry::parseFile()
{
    // open our given file path in read mode ("r").
    // and text mode ("t")
    Stream input(mFilePath, "rt");

    mFileName = input.getFileName();
	
	std::vector<Vector3>	tempVertices;
	std::vector<Vector3>	tempNormals;
	std::vector<Vector3>	tempTexCoords;
	std::vector<Vector4>	tempColors;

    // we read the file line by line until we are at the end
    while(!input.eof())
    {
        std::string curLine = input.readLine();
        // we have an empty line or a comment (starts with #)
        if(curLine.compare("") == 0 || curLine[0] == '#')
        {
            continue;
        }
        Tokenizer tokenizer(curLine);
        tokenizer.tokenize();

        if(tokenizer.getNumTokens() == 0)
        {
            continue;
        }

        std::vector<std::string> tokens = tokenizer.getTokens();

        // vertices
        if(tokens[0].compare("v") == 0)
        {
            Vector3 curVertex;
			for(size_t i = 1; i < tokens.size(); ++i)
			{
				curVertex.elements[i - 1] = atof(tokens[i].c_str());
			}

            tempVertices.push_back(curVertex);
        }
        // normals
        else if(tokens[0].compare("vn") == 0)
        {
            Vector3 curNormal;
			for(size_t i = 1; i < tokens.size(); ++i)
			{
				curNormal.elements[i - 1] = atof(tokens[i].c_str());
			}

            tempNormals.push_back(curNormal);
        }
        // texture coordinates
        else if(tokens[0].compare("vt") == 0)
        {
            Vector3 curTexCoord;
			for(size_t i = 1; i < tokens.size(); ++i)
			{
				curTexCoord.elements[i - 1] = atof(tokens[i].c_str());
			}
            tempTexCoords.push_back(curTexCoord);
        }
        // colors. this is an extension needed only for the assignments. the standard
        // obj file format does not have vertex colors
        else if(tokens[0].compare("vc") == 0)
        {
			Vector4 curColor;
			for(size_t i = 1; i < tokens.size(); ++i)
			{
				curColor.elements[i - 1] = atof(tokens[i].c_str());
			}
            tempColors.push_back(curColor);
        }
        // faces. in case of quads we convert to two triangles
        else if(tokens[0].compare("f") == 0)
        {
			if(tokens.size() == 4)
			{
				mPrimitiveType = TRIANGLES;
			}
			else if(tokens.size() == 5)
			{
				mPrimitiveType = QUADS;
			}
			// no supported primitive type
			else
			{
				continue;
			}
			
			typedef enum
			{
				vertex = 0,
				texcoord = 1,
				normal = 2,
				color = 3
			}
			facePointParam;
			
			// we loop over every vertex in the face
			for(size_t i = 1; i < tokens.size(); ++i)
			{
				facePointParam curParam = vertex;
				size_t numParams = std::count(tokens[i].begin(), tokens[i].end(), '/');
				size_t lastDelimiterIndex = -1;
				
				std::string remainderString = tokens[i];
				
				// we loop over the v/t/n/c construct part by part by reading until the first
				// occurence of /, converting the string to the index of the component, and then removing this
				// part of the string
				for(size_t j = 0; j < (numParams + 1); ++j)
				{
					size_t firstDelimiter = remainderString.find_first_of("/");
					
					std::string curString = remainderString.substr(lastDelimiterIndex + 1, firstDelimiter);
					
					if(curString.compare("") != 0)
					{					
						size_t index = atoi(curString.c_str());
						switch (curParam) {
							case vertex:
								mVertices.push_back(tempVertices[index]);
								break;
							case texcoord:
								mTexCoords.push_back(tempTexCoords[index]);
								break;
							case normal:
								mNormals.push_back(tempNormals[index]);
								break;
							case color:
								mColors.push_back(tempColors[index]);
								break;
								
							default:
								break;
						}
					}
					
					remainderString = remainderString.substr(firstDelimiter + 1,
															 remainderString.size() - firstDelimiter - 1);
					
                    curParam = (facePointParam)(((uint32_t)curParam) + 1);
					
				}				
			}
        }
        // everything else, we are not interested
        else
        {
            // not handeled
        }
    }
	
	convertQuadsToTriangles();
}