Exemple #1
0
poMesh3D::poMesh3D( int _numRows, int _numColumns )
{
    numRows = _numRows;
    numColumns = _numColumns;
    
    vertexList.resize( numRows*numColumns );
    
    for( int i=0; i<numRows; i++ )
    {
        for( int j=0; j<numColumns; j++ )
        {
            getVertex( i,j ).position.set( i*10,j*10, 0 );
        }
    }
    
    for( int i=0; i<numRows-1; i++ )
    {
        for( int j=0; j<numColumns-1; j++ )
        {
            int indexA = getVertexIndex(i,j);
            int indexB = getVertexIndex(i+1,j);
            int indexC = getVertexIndex(i,j+1);
            int indexD = getVertexIndex(i+1,j+1);
            addTriangle( indexA, indexB, indexC );
            addTriangle( indexD, indexC, indexB );
        }
    }
    
    calculateNormals();
}
Exemple #2
0
// read through the input file and hook up the graph accordingly
void hookupGraph(Graph *g, FILE *inputFile)
{
  int maxLineLen = 1000;  // maximum length of a line in the file
  char line[maxLineLen];  // will hold one line of the file at a time
  char delim[] = " \t\r\n\f\v";
  char *token;
  int edgeIndex = 0;

  while(fgets(line, maxLineLen, inputFile)){
    // 1st token in line is the source vertex
    if((token = strtok(line, delim))){
      int vertIndex1 = getVertexIndex(g, token);
      Vertex *vert1 = g->vertices+vertIndex1;
      // loop through and add all edges/ConnectorElements
      while((token = strtok(NULL, delim))){
        int vertIndex2 = getVertexIndex(g, token);
        // if index2 < index1, then we ignore it because we already added it
        if(vertIndex1 < vertIndex2){
          Vertex *vert2 = g->vertices+vertIndex2;
          Edge *ep = g->edges+edgeIndex;
          ConnectorElement *con = g->connectors+(2*edgeIndex);
          connect(vert1, ep, con);
          con = g->connectors+(2*edgeIndex+1);
          connect(vert2, ep, con);
          edgeIndex++;
        }
      }
    }
  }
}
/**
 * Atualiza o vértice
 * @param orig vértice de origem
 * @param dest vértice de destino
 * @param stat tipo de operação
 */
void update_aresta(int orig, int dest, int stat) {
    int i = getVertexIndex(orig),
        j = getVertexIndex(dest);

    if(i == count) {
        puts("Vérice origem não existe");
        return;
    }

    if(j == count) {
        puts("Vertice de destino não encontrado");
        return;
    }

    t_edge *here, *aux, *before;

    here = aux = before = NULL;

    here = edges[i];

    while (here != NULL)
        if (here->dest == j) {
            if(stat) {
                puts("Aresta repetida");
                return;
            } else
                break;
        } else {
            before = here;
            here = here->next;
        }

    if(stat) {
        aux = createEdge(j);

        if(before == NULL)
            edges[i] = aux;
        else
            before->next = aux;

        puts("Aresta inserida com sucesso");
    } else {

        if(before == NULL) {
            aux = here;
            edges[i] = here->next;
        } else {
            aux = before->next;
            before->next = aux->next;
        }

        free(aux);
        aux = NULL;

        puts("Aresta removida com sucesso");
    }

}
int peano::integration::dataqueries::CartesianGridWriterProxy::getVertexIndex( const tarch::la::Vector<2,double>& position ) {
  tarch::la::Vector<3,double> position3D;
  position3D(0) = position(0);
  position3D(1) = position(1);
  position3D(2) = 0.0;
  return getVertexIndex(position3D);
}
Exemple #5
0
poSphere3D::poSphere3D( int _numRows, int _numColumns, float _radius ) : poMesh3D(_numRows,_numColumns)
{
    radius = _radius;
    
	float dA =  360.f / (float)(numColumns-1);
	float dB =  180.f / (float)(numRows-1);
    
	for( int i=0; i<numRows; i++ )
	{
		for( int j=0; j<numColumns; j++ )
		{
			int N = getVertexIndex(i,j);
            if ( N==-1 || N < 0 || N >= (int)vertexList.size() )
            {
                printf("ERROR\n");
                continue;
            }
			float A = -1.f * dA * j;
			float B = 90 - dB * i;
			
			vertexList[N].position.set( cos_deg(B)*cos_deg(A)*radius, sin_deg(B)*radius, cos_deg(B)*sin_deg(A)*radius );
		}
	}
    
	calculateNormals();
}
int tarch::plotter::griddata::regular::CartesianGridArrayWriter::getCellIndex( const tarch::la::Vector<2,double>& position ) {
  tarch::la::Vector<3,double> position3D;
  position3D(0) = position(0);
  position3D(1) = position(1);
  position3D(2) = 0.0;
  return getVertexIndex(position3D);
}
Exemple #7
0
FbxT getElement(const KFbxLayerElementTemplate<FbxT>* pLayerElement,
    const KFbxMesh* fbxMesh,
    int nPolygon, int nPolyVertex, int nMeshVertex)
{
    return pLayerElement->GetDirectArray().GetAt(getVertexIndex(
        pLayerElement, fbxMesh, nPolygon, nPolyVertex, nMeshVertex));
}
Exemple #8
0
void TetMesh::computeGradient(int element, const double * U, int numFields, double * grad) const
{
  // grad is 9 x numFields
  // grad is constant inside a tet
  Vec3d vtx[4];
  for(int i=0; i<4; i++)
    vtx[i] = *getVertex(element,i);

  // form M =
  // [b - a]
  // [c - a]
  // [d - a]

  Mat3d M(vtx[1] - vtx[0], vtx[2] - vtx[0], vtx[3] - vtx[0]);
  Mat3d MInv = inv(M);
  //printf("M=\n");
  //M.print();

  for(int field=0; field<numFields; field++)
  {
    // form rhs =
    // [U1 - U0]
    // [U2 - U0]
    // [U3 - U0]
    const double * u[4];
    for(int i=0; i<4; i++)
      u[i] = &U[3 * numVertices * field + 3 * getVertexIndex(element, i)];

    Vec3d rows[3];
    for(int i=0; i<3; i++)
      rows[i] = Vec3d(u[i+1]) - Vec3d(u[0]);

    Mat3d rhs(rows);
    //printf("rhs=\n");
    //rhs.print();

    Mat3d gradM = trans(MInv * rhs);
    gradM.convertToArray(&grad[9 * field]);

/*
    // test gradient
    if (field == 0)
    {
      printf("----\n");
      printf("0: pos: %.15f %.15f %.15f | uExact: %.15f %.15f %.15f\n", vtx[0][0], vtx[0][1], vtx[0][2], u[0][0], u[0][1], u[0][2]);
      for(int vertex=0; vertex<3; vertex++)
      {
        Vec3d u1 = Vec3d(u[vertex+1]);
        printf("%d: ", vertex+1);
        printf("pos: %.15f %.15f %.15f | uExact: %.15f %.15f %.15f | ", vtx[vertex+1][0], vtx[vertex+1][1], vtx[vertex+1][2], u1[0], u1[1], u1[2]);
        Vec3d u1approx = Vec3d(u[0]) + gradM * (vtx[vertex+1] - vtx[0]);
        printf("uApprox: %.15f %.15f %.15f\n", u1approx[0], u1approx[1], u1approx[2]);
      }
      printf("----\n");
    }
*/
  }
}
Exemple #9
0
void CTerrainData::AddNode(int x,int y,int tx,int ty,unsigned char dir,int level,int father)
{
	if (!isCellIn(x,y))
	{
		return;
	}
	//if (((x!=tx) || (y!=ty))/* && (dir!=DIR_INVALID)*/)
	{
		if (getCell(x,y)->uAttribute&TERRAIN_ATT_TYPE_BALK)
		{
			return;
		}
		if (m_Searched[getVertexIndex(x,y)])// 可检查节点是否访问过
		{
			return;
		}
	}

	m_nNodeCount++;
	int p = m_nNodeCount;
	int f = level + (7*abs(x-tx)+7*abs(y-ty)+3*abs(abs(x-tx)-abs(y-ty))) / 2;//启发函数定义
	while( p > 1 )
	{
		int q = p >> 1;
		if( f < node[q].f )
			node[p] = node[q];
		else
			break;
		p = q;
	}
	node[p].x = x;
	node[p].y = y;
	node[p].f = f;
	node[p].level = level;
	node[p].n = m_nAllNodeCount;

	assert(m_nAllNodeCount<MAX_ALLNODE);

	m_allnode[m_nAllNodeCount].dir = dir;
	m_allnode[m_nAllNodeCount].father = father;
	m_nAllNodeCount++;

	m_Searched[getVertexIndex(x,y)]=true;
}
Exemple #10
0
poVertex3D&     poMesh3D::getVertex( int row, int col )
{
    if ( row < 0 || row >= numRows || col < 0 || col >= numColumns )
    {
        printf("ERROR: poMesh3D::getVertex out of bounds (%d,%d) of (%d,%d)\n", row, col, numRows, numColumns );
        return poShape3D::errorVertex;
    }
    
    int index = getVertexIndex(row,col);
    return vertexList[ index ];
}
void TetMesh::getElementEdges(int el, int * edgeBuffer) const
{
	int v[4];
	for(int i=0; i<4; i++)
		v[i] = getVertexIndex(el,i);

	int edgeMask[6][2] = {
			{ 0, 1 }, { 1, 2 }, { 2, 0 },
			{ 0, 3 }, { 1, 3 }, { 2, 3 } };

	for(int edge=0; edge<6; edge++)
	{
		edgeBuffer[2*edge+0] = v[edgeMask[edge][0]];
		edgeBuffer[2*edge+1] = v[edgeMask[edge][1]];
	}
}
Exemple #12
0
void Map::init(DBAccessor& dba)
{
	std::string texture_file_name;

	getSettings(dba,mapId,texture_file_name);
	initTexture(texture_file_name);
	getVertex(dba,mapId);
	getVertexIndex(dba,mapId);
	
	
	
	
	/*
	//Vertexの内容を標準出力に表示する
	std::cout<<"mapVertex"<<std::endl;
	int imax = mapVertex.size();
	
	for(int i = 0; i < imax; i++)
	{
		std::cout << i << ", ";
		std::cout << mapVertex[i].longitude << ", ";
		std::cout << mapVertex[i].latitude << ", ";
		std::cout << mapVertex[i].u << ", ";
		std::cout << mapVertex[i].v;
		std::cout<<std::endl;
	}
	
	std::cout<<std::endl;
	std::cout<<"mapVertexIndex"<<std::endl;
	imax = mapVertexIndex.size();
	for(int i = 0; i < imax; i++)
	{
		std::cout << i << ": ";
		int jmax = mapVertexIndex[i].size();
		for (int j = 0; j < jmax; j++)
		{
			std::cout << mapVertexIndex[i][j].vertexIndex << ", ";
		}
		std::cout << std::endl;
	}
	*/
}
Exemple #13
0
//===========================================================================
bool cLoadFileOBJ(cMesh* a_mesh, const string& a_fileName)
{
    cOBJModel fileObj;

    // load file into memory. If an error occurs, exit.
    if (!fileObj.LoadModel(a_fileName.c_str())) { return (false); };

    // get information about mesh
    cWorld* world = a_mesh->getParentWorld();

    // clear all vertices and triangle of current mesh
    a_mesh->clear();

    // get information about file
    int numMaterials = fileObj.m_OBJInfo.m_materialCount;
    int numNormals = fileObj.m_OBJInfo.m_normalCount;
    int numTexCoord = fileObj.m_OBJInfo.m_texCoordCount;

    // extract materials
    vector<cMaterial> materials;

    // object has no material properties
    if (numMaterials == 0)
    {
        // create a new child
        cMesh *newMesh = a_mesh->createMesh();
        a_mesh->addChild(newMesh);

        // Give him a default color
        a_mesh->setVertexColor(cColorb(255,255,255,255),1);
        a_mesh->useColors(1,1);
        a_mesh->useMaterial(0,1);
        a_mesh->enableTransparency(0,1);
    }

    // object has material properties. Create a child for each material
    // property.
    else
    {

        int i = 0;
        bool found_transparent_material = false;

        while (i < numMaterials)
        {
            // create a new child
            cMesh *newMesh = a_mesh->createMesh();
            a_mesh->addChild(newMesh);

            // get next material
            cMaterial newMaterial;
            cMaterialInfo material = fileObj.m_pMaterials[i];

            int textureId = material.m_textureID;
            if (textureId >= 1)
            {
                cTexture2D *newTexture = world->newTexture();
                int result = newTexture->loadFromFile(material.m_texture);

                // If this didn't work out, try again in the obj file's path
                if (result == 0) {

                  char model_dir[1024];
                  const char* fname = a_fileName.c_str();

                  find_directory(model_dir,fname);

                  char new_texture_path[1024];
                  sprintf(new_texture_path,"%s/%s",model_dir,material.m_texture);

                  result = newTexture->loadFromFile(new_texture_path);
                }

                if (result) newMesh->setTexture(newTexture);

                // We really failed to load a texture...
                else {
#ifdef _WIN32
                  // CHAI_DEBUG_PRINT("Could not load texture map %s\n",material.m_texture);
#endif
                }
            }

            float alpha = material.m_alpha;
            if (alpha < 1.0) {
              newMesh->enableTransparency(1,0);
              found_transparent_material = true;
            }

            // get ambient component:
            newMesh->m_material.m_ambient.setR(material.m_ambient[0]);
            newMesh->m_material.m_ambient.setG(material.m_ambient[1]);
            newMesh->m_material.m_ambient.setB(material.m_ambient[2]);
            newMesh->m_material.m_ambient.setA(alpha);

            // get diffuse component:
            newMesh->m_material.m_diffuse.setR(material.m_diffuse[0]);
            newMesh->m_material.m_diffuse.setG(material.m_diffuse[1]);
            newMesh->m_material.m_diffuse.setB(material.m_diffuse[2]);
            newMesh->m_material.m_diffuse.setA(alpha);

            // get specular component:
            newMesh->m_material.m_specular.setR(material.m_specular[0]);
            newMesh->m_material.m_specular.setG(material.m_specular[1]);
            newMesh->m_material.m_specular.setB(material.m_specular[2]);
            newMesh->m_material.m_specular.setA(alpha);

            // get emissive component:
            newMesh->m_material.m_emission.setR(material.m_emmissive[0]);
            newMesh->m_material.m_emission.setG(material.m_emmissive[1]);
            newMesh->m_material.m_emission.setB(material.m_emmissive[2]);
            newMesh->m_material.m_emission.setA(alpha);

            // get shininess
            newMaterial.setShininess((GLuint)(material.m_shininess));

            i++;
        }

        // Enable material property rendering
        a_mesh->useColors(0,1);
        a_mesh->useMaterial(1,1);

        // Mark the presence of transparency in the root mesh; don't
        // modify the value stored in children...
        a_mesh->enableTransparency(found_transparent_material,0);
        
    }

    // Keep track of vertex mapping in each mesh; maps "old" vertices
    // to new vertices
    int nMeshes = a_mesh->getNumChildren();
    vertexIndexSet_uint_map* vertexMaps = new vertexIndexSet_uint_map[nMeshes];
    vertexIndexSet_uint_map::iterator vertexMapIter;

    // build object
    {
        int i = 0;

        // get triangles
        int numTriangles = fileObj.m_OBJInfo.m_faceCount;
        int j = 0;
        while (j < numTriangles)
        {
            // get next face
            cFace face = fileObj.m_pFaces[j];

            // get material index attributed to the face
            int objIndex = face.m_materialIndex;

            // the mesh that we're reading this triangle into
            cMesh* curMesh = (cMesh*)a_mesh->getChild(objIndex);

            // create a name for this mesh if necessary (over-writing a previous
            // name if one has been written)
            if ( (face.m_groupIndex >= 0) && (fileObj.m_groupNames.size() > 0) )
              strncmp(curMesh->m_objectName,fileObj.m_groupNames[face.m_groupIndex],CHAI_MAX_OBJECT_NAME_LENGTH);

            // get the vertex map for this mesh
            vertexIndexSet_uint_map* curVertexMap = &(vertexMaps[objIndex]);

            // number of vertices on face
            int vertCount = face.m_numVertices;

            if (vertCount >= 3) {

                int indexV1 = face.m_pVertexIndices[0];

                if (g_objLoaderShouldGenerateExtraVertices==false) {
                  vertexIndexSet vis(indexV1);
                  if (numNormals  > 0) vis.nIndex = face.m_pNormalIndices[0];
                  if (numTexCoord > 0) vis.tIndex = face.m_pTextureIndices[0];
                  indexV1 = getVertexIndex(curMesh, &fileObj, curVertexMap, vis);
                }                

                for (int triangleVert = 2; triangleVert < vertCount; triangleVert++)
                {
                    int indexV2 = face.m_pVertexIndices[triangleVert-1];
                    int indexV3 = face.m_pVertexIndices[triangleVert];
                    if (g_objLoaderShouldGenerateExtraVertices==false) {
                      vertexIndexSet vis(indexV2);
                      if (numNormals  > 0) vis.nIndex = face.m_pNormalIndices[triangleVert-1];
                      if (numTexCoord > 0) vis.tIndex = face.m_pTextureIndices[triangleVert-1];
                      indexV2 = getVertexIndex(curMesh, &fileObj, curVertexMap, vis);
                      vis.vIndex = indexV3;
                      if (numNormals  > 0) vis.nIndex = face.m_pNormalIndices[triangleVert];
                      if (numTexCoord > 0) vis.tIndex = face.m_pTextureIndices[triangleVert];
                      indexV3 = getVertexIndex(curMesh, &fileObj, curVertexMap, vis);
                    }                      

                    // For debugging, I want to look for degenerate triangles, but
                    // I don't want to assert here.
                    if (indexV1 == indexV2 || indexV2 == indexV3 || indexV1 == indexV3) {
                      
                    }

                    unsigned int indexTriangle;

                    // create triangle:
                    if (g_objLoaderShouldGenerateExtraVertices==false) {                    
                      indexTriangle =
                        curMesh->newTriangle(indexV1,indexV2,indexV3);
                    }
                    else {
                      indexTriangle =
                        curMesh->newTriangle(
                          fileObj.m_pVertices[indexV1],
                          fileObj.m_pVertices[indexV2],
                          fileObj.m_pVertices[indexV3]
                        );
                    }
                    
                    cTriangle* curTriangle = curMesh->getTriangle(indexTriangle,false);

                    // assign normals:
                    if (numNormals > 0)
                    {
                        // set normals
                        curTriangle->getVertex0()->setNormal(face.m_pNormals[0]);
                        curTriangle->getVertex1()->setNormal(face.m_pNormals[triangleVert-1]);
                        curTriangle->getVertex2()->setNormal(face.m_pNormals[triangleVert]);
                    }

                    // assign texture coordinates
                    if (numTexCoord > 0)
                    {
                        // set texture coordinates
                        curTriangle->getVertex0()->setTexCoord(face.m_pTexCoords[0]);
                        curTriangle->getVertex1()->setTexCoord(face.m_pTexCoords[triangleVert-1]);
                        curTriangle->getVertex2()->setTexCoord(face.m_pTexCoords[triangleVert]);
                    }
                }
            }
            else {

              // This faces doesn't have 3 vertices... this line is just
              // here for debugging, since this should never happen, but
              // I don't want to assert here.
              
            }
            j++;
        }
        i++;
    }

    delete [] vertexMaps;

    // if no normals were specified in the file, compute them
    // based on triangle faces
    if (numNormals == 0) {
      a_mesh->computeAllNormals(true);
    }

    // compute boundary boxes
    a_mesh->computeBoundaryBox(true);

    // update global position in world
    if (world != 0) world->computeGlobalPositions(true);

    // return success
    return (true);
}
Exemple #14
0
osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh(
    KFbxNode* pNode,
    KFbxMesh* fbxMesh,
    std::vector<StateSetContent>& stateSetList,
    const char* szName)
{
    GeometryMap geometryMap;

    osg::Geode* pGeode = new osg::Geode;
    pGeode->setName(szName);

    const KFbxLayerElementNormal* pFbxNormals = 0;
    const KFbxLayerElementVertexColor* pFbxColors = 0;
    const KFbxLayerElementMaterial* pFbxMaterials = 0;

    const KFbxVector4* pFbxVertices = fbxMesh->GetControlPoints();

    // scan layers for Normals, Colors and Materials elements (this will get the first available elements)...
    for (int cLayerIndex = 0; cLayerIndex < fbxMesh->GetLayerCount(); cLayerIndex++)
    {
        const KFbxLayer* pFbxLayer = fbxMesh->GetLayer(cLayerIndex);
        if (!pFbxLayer)
            continue;

        // get normals, colors and materials...
        if (!pFbxNormals)
            pFbxNormals = pFbxLayer->GetNormals();
        if (!pFbxColors)
            pFbxColors = pFbxLayer->GetVertexColors();
        if (!pFbxMaterials)
            pFbxMaterials = pFbxLayer->GetMaterials();
    }

    // look for UV elements (diffuse, opacity, reflection, emissive, ...) and get their channels names...
    std::string diffuseChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sDiffuse);
    std::string opacityChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sTransparentColor);
    std::string emissiveChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sEmissive);
    // look for more UV elements here...

    // UV elements...
    const KFbxLayerElementUV* pFbxUVs_diffuse = getUVElementForChannel(diffuseChannel, KFbxLayerElement::eDIFFUSE_TEXTURES, fbxMesh);
    const KFbxLayerElementUV* pFbxUVs_opacity = getUVElementForChannel(opacityChannel, KFbxLayerElement::eTRANSPARENT_TEXTURES, fbxMesh);
    const KFbxLayerElementUV* pFbxUVs_emissive = getUVElementForChannel(emissiveChannel, KFbxLayerElement::eEMISSIVE_TEXTURES, fbxMesh);
    // more UV elements here...

    // check elements validity...
    if (!layerElementValid(pFbxNormals)) pFbxNormals = 0;
    if (!layerElementValid(pFbxColors)) pFbxColors = 0;

    if (!layerElementValid(pFbxUVs_diffuse)) pFbxUVs_diffuse = 0;
    if (!layerElementValid(pFbxUVs_opacity)) pFbxUVs_opacity = 0;
    if (!layerElementValid(pFbxUVs_emissive)) pFbxUVs_emissive = 0;
    // more here...

    int nPolys = fbxMesh->GetPolygonCount();

    int nDeformerCount = fbxMesh->GetDeformerCount(KFbxDeformer::eSKIN);
    int nDeformerBlendShapeCount = fbxMesh->GetDeformerCount(KFbxDeformer::eBLENDSHAPE);

    GeometryType geomType = GEOMETRY_STATIC;

    //determine the type of geometry
    if (nDeformerCount)
    {
        geomType = GEOMETRY_RIG;
    }
    else if (nDeformerBlendShapeCount)
    {
        geomType = GEOMETRY_MORPH;
    }

    FbxToOsgVertexMap fbxToOsgVertMap;
    OsgToFbxNormalMap osgToFbxNormMap;

    // First add only triangles and quads (easy to split into triangles without
    // more processing)
    // This is the reason we store polygons references:

    PolygonRefList polygonRefList;

    for (int i = 0, nVertex = 0; i < nPolys; ++i)
    {
        int lPolygonSize = fbxMesh->GetPolygonSize(i);

        int materialIndex = getPolygonIndex(pFbxMaterials, i);

        osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap,
            stateSetList, geomType, materialIndex,
            pFbxNormals != 0,
            pFbxUVs_diffuse != 0,
            pFbxUVs_opacity != 0,
            pFbxUVs_emissive != 0,
            // more UV elements here...
            pFbxColors != 0,
            options,
            lightmapTextures);

        osg::Array* pVertices = pGeometry->getVertexArray();
        osg::Array* pNormals = pGeometry->getNormalArray();

        // get texture coordinates...
        osg::Array* pTexCoords_diffuse = pGeometry->getTexCoordArray(StateSetContent::DIFFUSE_TEXTURE_UNIT);
        osg::Array* pTexCoords_opacity = pGeometry->getTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT);
        osg::Array* pTexCoords_emissive = pGeometry->getTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT);
        // more texture coordinates here...

        osg::Array* pColors = pGeometry->getColorArray();

        if (lPolygonSize == 3)
        {
            // Triangle
            readMeshTriangle(fbxMesh, i,
                0, 1, 2,
                nVertex, nVertex+1, nVertex+2,
                fbxToOsgVertMap, osgToFbxNormMap,
                pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors,
                pGeometry,
                pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors);
            nVertex += 3;
        }
        else if (lPolygonSize == 4)
        {
            // Quad - Convert to triangles
            // Use some fast specialized code to see how the should be decomposed
            // Two cases : Split at '02' (012 and 023), or split at '13 (013 and 123)
            bool split02 = quadSplit02(fbxMesh, i, 0, 1, 2, 3, pFbxVertices);
            int p02 = split02 ? 2 : 3; // Triangle 0, point 2
            int p10 = split02 ? 0 : 1; // Triangle 1, point 0
            readMeshTriangle(fbxMesh, i,
                0, 1, p02,
                nVertex, nVertex+1, nVertex+p02,
                fbxToOsgVertMap, osgToFbxNormMap,
                pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors,
                pGeometry,
                pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors);
            readMeshTriangle(fbxMesh, i,
                p10, 2, 3,
                nVertex+p10, nVertex+2, nVertex+3,
                fbxToOsgVertMap, osgToFbxNormMap,
                pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors,
                pGeometry,
                pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors);
            nVertex += 4;
        }
        else if (tessellatePolygons)
        {
            // Polygons - Store to add after triangles
            polygonRefList.push_back(PolygonRef(pGeometry, i, nVertex));
            nVertex += lPolygonSize;
        }
        else
        {
            int nVertex0 = nVertex;
            nVertex += (std::min)(2, lPolygonSize);

            for (int j = 2; j < lPolygonSize; ++j, ++nVertex)
            {
                readMeshTriangle(fbxMesh, i,
                    0, j - 1, j,
                    nVertex0, nVertex - 1, nVertex,
                    fbxToOsgVertMap, osgToFbxNormMap,
                    pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors,
                    pGeometry,
                    pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors);
            }
        }
    }

    for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i)
    {
        osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
        osg::DrawArrays* pDrawArrays = new osg::DrawArrays(
            GL_TRIANGLES, 0, pGeometry->getVertexArray()->getNumElements());
        pGeometry->addPrimitiveSet(pDrawArrays);
    }

    // Now add polygons - Convert to triangles
    // We put vertices in their own PrimitiveSet with Mode=POLYGON; then run the
    // Tessellator on the Geometry which should tessellate the polygons
    // automagically.
    for (PolygonRefList::iterator it = polygonRefList.begin(), itEnd=polygonRefList.end();
        it != itEnd; ++it)
    {
        int i = it->numPoly;
        int lPolygonSize = fbxMesh->GetPolygonSize(i);
        //int materialIndex = getPolygonIndex(pFbxMaterials, i);
        osg::Geometry* pGeometry = it->pGeometry;

        osg::Array* pVertices = pGeometry->getVertexArray();
        osg::Array* pNormals = pGeometry->getNormalArray();
        osg::Array* pTexCoords_diffuse = pGeometry->getTexCoordArray(StateSetContent::DIFFUSE_TEXTURE_UNIT);
        osg::Array* pTexCoords_opacity = pGeometry->getTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT);
        osg::Array* pTexCoords_emissive = pGeometry->getTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT);
        osg::Array* pColors = pGeometry->getColorArray();
        // Index of the 1st vertex of the polygon in the geometry
        int osgVertex0 = pVertices->getNumElements();

        for (int j = 0, nVertex = it->nVertex; j<lPolygonSize; ++j, ++nVertex)
        {
            int v0 = fbxMesh->GetPolygonVertex(i, j);
            fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->getNumElements())));
            addVec3ArrayElement(*pVertices, pFbxVertices[v0]);
            if (pNormals)
            {
                int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, j, nVertex);
                osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements()), n0));
                addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0));
            }

            // add texture maps data (avoid duplicates)...
            if (pTexCoords_diffuse)
            {
                addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, j, nVertex));
            }
            if (pTexCoords_opacity && (pTexCoords_opacity != pTexCoords_diffuse))
            {
                addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, j, nVertex));
            }

            // Only spherical reflection maps are supported (so do not add coordinates for the reflection map)

            if (pTexCoords_emissive && (pTexCoords_emissive != pTexCoords_opacity) && (pTexCoords_emissive != pTexCoords_diffuse))
            {
                addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, j, nVertex));
            }
            // add more texture maps here...

            if (pColors)
            {
                addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, j, nVertex));
            }
        }

        osg::DrawArrays* pDrawArrays = new osg::DrawArrays(
            GL_POLYGON, osgVertex0, pGeometry->getVertexArray()->getNumElements() - osgVertex0);
        pGeometry->addPrimitiveSet(pDrawArrays);
    }

    for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i)
    {
        osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();

        // Now split polygons if necessary
        osgUtil::Tessellator tessellator;
        tessellator.retessellatePolygons(*pGeometry);

        if (pGeode->getNumDrawables() > 1)
        {
            std::stringstream ss;
            ss << pGeode->getName() << " " << i + 1;
            pGeometry->setName(ss.str());
        }
        else
        {
            pGeometry->setName(pGeode->getName());
        }
    }

    if (geomType == GEOMETRY_RIG)
    {
        typedef std::map<osg::ref_ptr<osg::Geometry>,
            osg::ref_ptr<osgAnimation::RigGeometry> > GeometryRigGeometryMap;
        GeometryRigGeometryMap old2newGeometryMap;

        for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i)
        {
            osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();

            osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry;
            pRig->setSourceGeometry(pGeometry);
            pRig->copyFrom(*pGeometry);
            old2newGeometryMap.insert(GeometryRigGeometryMap::value_type(
                pGeometry, pRig));
            pRig->setDataVariance(osg::Object::DYNAMIC);
            pRig->setUseDisplayList( false );
            pGeode->setDrawable(i, pRig);

            pRig->setInfluenceMap(new osgAnimation::VertexInfluenceMap);
            pGeometry = pRig;
        }

        for (int i = 0; i < nDeformerCount; ++i)
        {
            KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(i, KFbxDeformer::eSKIN);
            int nClusters = pSkin->GetClusterCount();
            for (int j = 0; j < nClusters; ++j)
            {
                KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j);
                //assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode());
                KFbxNode* pBone = pCluster->GetLink();

                KFbxXMatrix transformLink;
                pCluster->GetTransformLinkMatrix(transformLink);
                KFbxXMatrix transformLinkInverse = transformLink.Inverse();
                const double* pTransformLinkInverse = transformLinkInverse;
                osg::Matrix bindMatrix(pTransformLinkInverse);

                int nIndices = pCluster->GetControlPointIndicesCount();
                int* pIndices = pCluster->GetControlPointIndices();
                double* pWeights = pCluster->GetControlPointWeights();

                for (int k = 0; k < nIndices; ++k)
                {
                    int fbxIndex = pIndices[k];
                    float weight = static_cast<float>(pWeights[k]);

                    for (FbxToOsgVertexMap::const_iterator it =
                        fbxToOsgVertMap.find(fbxIndex);
                        it != fbxToOsgVertMap.end() &&
                        it->first == fbxIndex; ++it)
                    {
                        GIPair gi = it->second;
                        osgAnimation::RigGeometry& rig =
                            dynamic_cast<osgAnimation::RigGeometry&>(
                            *old2newGeometryMap[gi.first]);
                        addBindMatrix(boneBindMatrices, pBone, bindMatrix, &rig);
                        osgAnimation::VertexInfluenceMap& vim =
                            *rig.getInfluenceMap();
                        osgAnimation::VertexInfluence& vi =
                            getVertexInfluence(vim, pBone->GetName());
                        vi.push_back(osgAnimation::VertexIndexWeight(
                            gi.second, weight));
                    }
                }
            }
        }
    }
    else if (geomType == GEOMETRY_MORPH)
    {
        for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i)
        {
            osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();

            osgAnimation::MorphGeometry& morph = dynamic_cast<osgAnimation::MorphGeometry&>(*pGeometry);

            pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(morph.getName()));

            //read morph geometry
            for (int nBlendShape = 0; nBlendShape < nDeformerBlendShapeCount; ++nBlendShape)
            {
                KFbxBlendShape* pBlendShape = KFbxCast<KFbxBlendShape>(fbxMesh->GetDeformer(nBlendShape, KFbxDeformer::eBLENDSHAPE));
                const int nBlendShapeChannelCount = pBlendShape->GetBlendShapeChannelCount();

                for (int nBlendShapeChannel = 0; nBlendShapeChannel < nBlendShapeChannelCount; ++nBlendShapeChannel)
                {
                    KFbxBlendShapeChannel* pBlendShapeChannel = pBlendShape->GetBlendShapeChannel(nBlendShapeChannel);
                    if (!pBlendShapeChannel->GetTargetShapeCount()) continue;

                    //Assume one shape
                    if (pBlendShapeChannel->GetTargetShapeCount() > 1)
                    {
                        OSG_WARN << "Multiple FBX Target Shapes, only the first will be used" << std::endl;
                    }
                    const KFbxGeometryBase* pMorphShape = pBlendShapeChannel->GetTargetShape(0);

                    const KFbxLayerElementNormal* pFbxShapeNormals = 0;
                    if (const KFbxLayer* pFbxShapeLayer = pMorphShape->GetLayer(0))
                    {
                        pFbxShapeNormals = pFbxShapeLayer->GetNormals();
                        if (!layerElementValid(pFbxShapeNormals)) pFbxShapeNormals = 0;
                    }

                    osg::Geometry* pMorphTarget = new osg::Geometry(morph);
                    pMorphTarget->setVertexArray(static_cast<osg::Array*>(
                        pMorphTarget->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
                    if (pFbxShapeNormals)
                    {
                        if (osg::Array* pNormals = pMorphTarget->getNormalArray())
                        {
                            pMorphTarget->setNormalArray(static_cast<osg::Array*>(
                                pNormals->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
                        }
                    }
                    pMorphTarget->setName(pMorphShape->GetName());
                    morph.addMorphTarget(pMorphTarget, 0.0f);

                    readAnimation(pNode, fbxScene, morph.getName(), pAnimationManager, fbxMesh,
                        nBlendShape, nBlendShapeChannel, (int)morph.getMorphTargetList().size() - 1);
                }
            }
        }

        int nMorphTarget = 0;
        for (int nBlendShape = 0; nBlendShape < nDeformerBlendShapeCount; ++nBlendShape)
        {
            KFbxBlendShape* pBlendShape = KFbxCast<KFbxBlendShape>(fbxMesh->GetDeformer(nBlendShape, KFbxDeformer::eBLENDSHAPE));
            const int nBlendShapeChannelCount = pBlendShape->GetBlendShapeChannelCount();

            for (int nBlendShapeChannel = 0; nBlendShapeChannel < nBlendShapeChannelCount; ++nBlendShapeChannel)
            {
                KFbxBlendShapeChannel* pBlendShapeChannel = pBlendShape->GetBlendShapeChannel(nBlendShapeChannel);
                if (!pBlendShapeChannel->GetTargetShapeCount()) continue;

                //Assume one shape again
                const KFbxGeometryBase* pMorphShape = pBlendShapeChannel->GetTargetShape(0);

                const KFbxLayerElementNormal* pFbxShapeNormals = 0;
                if (const KFbxLayer* pFbxShapeLayer = pMorphShape->GetLayer(0))
                {
                    pFbxShapeNormals = pFbxShapeLayer->GetNormals();
                    if (!layerElementValid(pFbxShapeNormals)) pFbxShapeNormals = 0;
                }

                const KFbxVector4* pControlPoints = pMorphShape->GetControlPoints();
                int nControlPoints = pMorphShape->GetControlPointsCount();
                for (int fbxIndex = 0; fbxIndex < nControlPoints; ++fbxIndex)
                {
                    osg::Vec3d vPos = convertVec3(pControlPoints[fbxIndex]);
                    for (FbxToOsgVertexMap::const_iterator it =
                        fbxToOsgVertMap.find(fbxIndex);
                        it != fbxToOsgVertMap.end() &&
                        it->first == fbxIndex; ++it)
                    {
                        GIPair gi = it->second;
                        osgAnimation::MorphGeometry& morphGeom =
                            dynamic_cast<osgAnimation::MorphGeometry&>(*gi.first);
                        osg::Geometry* pGeometry = morphGeom.getMorphTarget(nMorphTarget).getGeometry();

                        if (pGeometry->getVertexArray()->getType() == osg::Array::Vec3dArrayType)
                        {
                            osg::Vec3dArray* pVertices = static_cast<osg::Vec3dArray*>(pGeometry->getVertexArray());
                            (*pVertices)[gi.second] = vPos;
                        }
                        else
                        {
                            osg::Vec3Array* pVertices = static_cast<osg::Vec3Array*>(pGeometry->getVertexArray());
                            (*pVertices)[gi.second] = vPos;
                        }

                        if (pFbxShapeNormals && pGeometry->getNormalArray())
                        {
                            if (pGeometry->getNormalArray()->getType() == osg::Array::Vec3dArrayType)
                            {
                                osg::Vec3dArray* pNormals = static_cast<osg::Vec3dArray*>(pGeometry->getNormalArray());
                                (*pNormals)[gi.second] = convertVec3(
                                    pFbxShapeNormals->GetDirectArray().GetAt(osgToFbxNormMap[gi]));
                            }
                            else
                            {
                                osg::Vec3Array* pNormals = static_cast<osg::Vec3Array*>(pGeometry->getNormalArray());
                                (*pNormals)[gi.second] = convertVec3(
                                    pFbxShapeNormals->GetDirectArray().GetAt(osgToFbxNormMap[gi]));
                            }
                        }
                    }
                }

                //don't put this in the for loop as we don't want to do it if the loop continues early
                ++nMorphTarget;
            }
        }
    }

    KFbxXMatrix fbxGeometricTransform;
    fbxGeometricTransform.SetTRS(
        pNode->GeometricTranslation.Get(),
        pNode->GeometricRotation.Get(),
        pNode->GeometricScaling.Get());
    const double* pGeometricMat = fbxGeometricTransform;
    osg::Matrix osgGeometricTransform(pGeometricMat);

    if (geomType == GEOMETRY_RIG)
    {
        KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN);
        if (pSkin->GetClusterCount())
        {
            KFbxXMatrix fbxTransformMatrix;
            pSkin->GetCluster(0)->GetTransformMatrix(fbxTransformMatrix);
            const double* pTransformMatrix = fbxTransformMatrix;
            osgGeometricTransform.postMult(osg::Matrix(pTransformMatrix));
        }
    }

    osg::Node* pResult = pGeode;

    if (!osgGeometricTransform.isIdentity())
    {
        osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(osgGeometricTransform);
        pMatTrans->addChild(pGeode);
        pResult = pMatTrans;
    }

    if (geomType == GEOMETRY_RIG)
    {
        //Add the geometry to the skeleton ancestor of one of the bones.
        KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN);
        if (pSkin->GetClusterCount())
        {
            osgAnimation::Skeleton* pSkeleton = getSkeleton(
                pSkin->GetCluster(0)->GetLink(), fbxSkeletons, skeletonMap);
            pSkeleton->addChild(pResult);
            return osgDB::ReaderWriter::ReadResult::FILE_LOADED;
        }
    }

    return osgDB::ReaderWriter::ReadResult(pResult);
}
Exemple #15
0
void readMeshTriangle(const KFbxMesh * fbxMesh, int i /*polygonIndex*/,
                      int posInPoly0, int posInPoly1, int posInPoly2,
                      int meshVertex0, int meshVertex1, int meshVertex2,
                      FbxToOsgVertexMap& fbxToOsgVertMap,
                      OsgToFbxNormalMap& osgToFbxNormMap,
                      const KFbxVector4* pFbxVertices,
                      const KFbxLayerElementNormal* pFbxNormals,
                      const KFbxLayerElementUV* pFbxUVs_diffuse,
                      const KFbxLayerElementUV* pFbxUVs_opacity,
                      const KFbxLayerElementUV* pFbxUVs_emissive,
                      const KFbxLayerElementVertexColor* pFbxColors,
                      osg::Geometry* pGeometry,
                      osg::Array* pVertices,
                      osg::Array* pNormals,
                      osg::Array* pTexCoords_diffuse,
                      osg::Array* pTexCoords_opacity,
                      osg::Array* pTexCoords_emissive,
                      osg::Array* pColors)
{
    int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0),
        v1 = fbxMesh->GetPolygonVertex(i, posInPoly1),
        v2 = fbxMesh->GetPolygonVertex(i, posInPoly2);

    fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->getNumElements())));
    fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v1, GIPair(pGeometry, pVertices->getNumElements() + 1)));
    fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->getNumElements() + 2)));

    addVec3ArrayElement(*pVertices, pFbxVertices[v0]);
    addVec3ArrayElement(*pVertices, pFbxVertices[v1]);
    addVec3ArrayElement(*pVertices, pFbxVertices[v2]);

    if (pNormals)
    {
        int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly0, meshVertex0);
        int n1 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly1, meshVertex1);
        int n2 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly2, meshVertex2);

        osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements()), n0));
        osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements() + 1), n1));
        osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements() + 2), n2));

        addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0));
        addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n1));
        addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n2));
    }

    // add texture maps data (avoid duplicates)...
    if (pTexCoords_diffuse)
    {
        addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, posInPoly0, meshVertex0));
        addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, posInPoly1, meshVertex1));
        addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, posInPoly2, meshVertex2));
    }
    if (pTexCoords_opacity && (pTexCoords_opacity != pTexCoords_diffuse))
    {
        addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, posInPoly0, meshVertex0));
        addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, posInPoly1, meshVertex1));
        addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, posInPoly2, meshVertex2));
    }

    // Only spherical reflection maps are supported (so do not add coordinates for the reflection map)

    if (pTexCoords_emissive && (pTexCoords_emissive != pTexCoords_opacity) && (pTexCoords_emissive != pTexCoords_diffuse))
    {
        addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly0, meshVertex0));
        addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly1, meshVertex1));
        addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly2, meshVertex2));
    }
    // add more texture maps here...

    if (pColors)
    {
        addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly0, meshVertex0));
        addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly1, meshVertex1));
        addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly2, meshVertex2));
    }
}