예제 #1
0
void MeshTools::createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh,
                                              bool(*predicate)(scene::IMeshBuffer*))
{
    core::array<scene::SSkinMeshBuffer*>& all_mb = mesh->getMeshBuffers();
    const int all_mb_size = all_mb.size();
    for (int i = 0; i < all_mb_size; i++)
    {
        scene::SSkinMeshBuffer* mb = all_mb[i];
        if (mb && predicate(mb))
        {
            mb->convertToTangents();
            const int index_count = mb->getIndexCount();
            uint16_t* idx = mb->getIndices();
            video::S3DVertexTangents* v =
                (video::S3DVertexTangents*)mb->getVertices();

            for (int i = 0; i < index_count; i += 3)
            {
                calculateTangents(
                    v[idx[i+0]].Normal,
                    v[idx[i+0]].Tangent,
                    v[idx[i+0]].Binormal,
                    v[idx[i+0]].Pos,
                    v[idx[i+1]].Pos,
                    v[idx[i+2]].Pos,
                    v[idx[i+0]].TCoords,
                    v[idx[i+1]].TCoords,
                    v[idx[i+2]].TCoords);

                calculateTangents(
                    v[idx[i+1]].Normal,
                    v[idx[i+1]].Tangent,
                    v[idx[i+1]].Binormal,
                    v[idx[i+1]].Pos,
                    v[idx[i+2]].Pos,
                    v[idx[i+0]].Pos,
                    v[idx[i+1]].TCoords,
                    v[idx[i+2]].TCoords,
                    v[idx[i+0]].TCoords);

                calculateTangents(
                    v[idx[i+2]].Normal,
                    v[idx[i+2]].Tangent,
                    v[idx[i+2]].Binormal,
                    v[idx[i+2]].Pos,
                    v[idx[i+0]].Pos,
                    v[idx[i+1]].Pos,
                    v[idx[i+2]].TCoords,
                    v[idx[i+0]].TCoords,
                    v[idx[i+1]].TCoords);
            }
        }
    }
}
예제 #2
0
파일: distance.c 프로젝트: vincent101/KNN
double tangentDistance(const double * imageOne, const double * imageTwo, 
  const int height, const int width, const int * choice, const double background){
  int i,numTangents=0,numTangentsRemaining;
  double ** tangents,dist;

  int size=width*height;

  for(i=0;i<maxNumTangents;++i) {
    if(choice[i]>0) numTangents++;
  }

  tangents=(double **)malloc(numTangents*sizeof(double *));
  for(i=0;i<numTangents;++i) {
    tangents[i]=(double *)malloc(size*sizeof(double));
  }

  calculateTangents(imageOne, tangents, numTangents, height, width, choice, background);

  numTangentsRemaining = normalizeTangents(tangents, numTangents, height, width);

  dist=calculateDistance(imageOne, imageTwo, (const double **) tangents, numTangentsRemaining, height, width);

  for(i=0;i<numTangents;++i) {
    free(tangents[i]);
  }
  free(tangents);

  return dist;
}
예제 #3
0
	void Mesh::createVPlane(Number w, Number h) { 
		Polygon *imagePolygon = new Polygon();
		
		imagePolygon->addVertex(0,0,0,0,0);
		imagePolygon->addVertex(w,0,0, 1, 0);		
		imagePolygon->addVertex(w,h,0, 1, 1);									
		imagePolygon->addVertex(0,h,0,0,1);	


		addPolygon(imagePolygon);
		
		for(int i=0; i < polygons.size(); i++) {
			for(int j=0; j < polygons[i]->getVertexCount(); j++) {
				polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - (w/2.0f);
				polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - (h/2.0f);
			}
		}

		calculateNormals();
		calculateTangents();
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;										
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;		
	}	
예제 #4
0
	void Mesh::createCone(Number height, Number radius, int numSegments) {
	
	
		setMeshType(Mesh::TRI_MESH);
		Number lastx = -1;
		Number lastz = -1;		
		for (int i=0 ; i < numSegments+1; i++) {
			Number pos = ((PI*2.0)/((Number)numSegments)) * i;
			Number x = sinf(pos) * radius;
			Number z = cosf(pos) * radius;
			
			if(i > 0) { // ie only construct faces one we have vertexes from i-1 to use.
				Polygon *polygon = new Polygon();
				polygon->addVertex(lastx,0,lastz,0,0);				
				polygon->addVertex(x,0,z, 1, 0);
				polygon->addVertex(0,height,0, 1, 1);				
				addPolygon(polygon);							
			

				polygon = new Polygon();	
				polygon->addVertex(x,0,z, 1, 1);												
				polygon->addVertex(lastx,0,lastz, 1, 1);																														
				polygon->addVertex(0,0,0,0,0);												
				addPolygon(polygon);			

								
			}
			lastx = x;
			lastz = z;	
		/*
			Polygon *polygon = new Polygon();
			polygon->addVertex(w,0,h, 1, 1);
			polygon->addVertex(0,0,h, 1, 0);
			polygon->addVertex(0,0,0,0,0);
			polygon->addVertex(w,0,0,0,1);
			addPolygon(polygon);			
			*/
        }
		
		for(int i=0; i < polygons.size(); i++) {
			for(int j=0; j < polygons[i]->getVertexCount(); j++) {
//				polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - (radius/2.0f);
				polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - (height/2.0f);
//				polygons[i]->getVertex(j)->z = polygons[i]->getVertex(j)->z - (radius/2.0f);	
			}
		}
		
		
		calculateNormals();
		calculateTangents();
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;										
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;			
	
	}
예제 #5
0
파일: mtd_0.c 프로젝트: caomw/CV_LieDeform
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[])
{
int row1,row2,col,ww;
int choice[]={1,1,1,1,1,1,1,1,1};
/*={0,0,0,0,0,0,1,0,0};*/
/*choice[]={1,1,1,1,1,1,0,0,0};*/
double * img1, *img2, *imgout,background=0.0;

/*1) Read */
/*test*/
img1= mxGetPr(prhs[0]);
/*train*/
img2= mxGetPr(prhs[1]);
/*choice =mxGetPr(prhs[2]);*/
row1= mxGetN(prhs[0]);
row2= mxGetN(prhs[0]);
col= mxGetM(prhs[0]);
ww=(int)sqrt(col);


/*2) Calculate the tangent space at train */
int i,numTangents=0,numTangentsRemaining;
double ** tangents;
  for(i=0;i<maxNumTangents;++i) {
   /*printf("nn %d,%\n",i,choice[i]);*/
    if(choice[i]>0) numTangents++;
  }

  tangents=(double **)malloc(numTangents*sizeof(double *));
  for(i=0;i<numTangents;++i) {
    tangents[i]=(double *)malloc(col*sizeof(double));
  }

  /* determine the tangents of the first image*/
   calculateTangents(img2, tangents, numTangents,ww,ww, choice, background);

  /* find the orthonormal tangent subspace */
  numTangentsRemaining = normalizeTangents(tangents, numTangents, ww, ww);

/*3) Project test onto the tangent space*/
plhs[0] =mxCreateDoubleMatrix(1,col, mxREAL);
imgout = mxGetPr(plhs[0]);

calculateClosest(img2, img1,tangents, numTangents, col,imgout);

  for(i=0;i<numTangents;++i) {
    free(tangents[i]);
  }
    free(tangents);
}
예제 #6
0
파일: mesh.cpp 프로젝트: nicktyson/rome
void mesh::loadMesh(std::string fileLocation) {
	//assumes pattern:
	//vert count, tri count
	//vertices, triangles, normals, texcoords
	std::ifstream fileStream(fileLocation);

	fileStream >> vertCount;
	fileStream >> triCount;

	triangles.resize(3 * triCount);
	normals.resize(3 * vertCount);
	vertices.resize(3 * vertCount);
	texCoords.resize(2 * vertCount);

	std::string trash;
	fileStream >> trash;

	//read and store vertex positions
	for(int i = 0; i < 3*vertCount; i++) {
		fileStream >> vertices[i];
	}

	fileStream >> trash;

	//read and store triangles (vertex indices)
	for(int j = 0; j < 3*triCount; j++) {
		fileStream >> triangles[j];
	}

	fileStream >> trash;

	//read and store normals
	for(int k = 0; k < 3*vertCount; k++) {
		fileStream >> normals[k];
	}

	fileStream >> trash;

	//read and store texture coordinates
	for(int l = 0; l < 2*vertCount; l++) {
		fileStream >> texCoords[l];
	}

	fileStream.close();

	calculateTangents();
	setupBuffers();
}
// Constructor. Copy the provided picoSurface_t structure into this object
RenderablePicoSurface::RenderablePicoSurface(picoSurface_t* surf,
											 const std::string& fExt)
: _shaderName(""),
  _dlRegular(0),
  _dlProgramVcol(0),
  _dlProgramNoVCol(0)
{
	// Get the shader from the picomodel struct. If this is a LWO model, use
	// the material name to select the shader, while for an ASE model the
	// bitmap path should be used.
	picoShader_t* shader = PicoGetSurfaceShader(surf);
	std::string rawName = "";

	if (shader != 0)
	{
		if (fExt == "lwo")
		{
			_shaderName = PicoGetShaderName(shader);
		}
		else if (fExt == "ase")
		{
			rawName = PicoGetShaderName(shader);
			std::string rawMapName = PicoGetShaderMapName(shader);
			_shaderName = cleanupShaderName(rawMapName);
		}
	}

	// If shader not found, fallback to alternative if available
	// _shaderName is empty if the ase material has no BITMAP
	// materialIsValid is false if _shaderName is not an existing shader
	if ((_shaderName.empty() || !GlobalMaterialManager().materialExists(_shaderName)) &&
		!rawName.empty())
	{
		_shaderName = cleanupShaderName(rawName);
	}

	// Capturing the shader happens later on when we have a RenderSystem reference

    // Get the number of vertices and indices, and reserve capacity in our
    // vectors in advance by populating them with empty structs.
    int nVerts = PicoGetSurfaceNumVertexes(surf);
    _nIndices = PicoGetSurfaceNumIndexes(surf);
    _vertices.resize(nVerts);
    _indices.resize(_nIndices);

    // Stream in the vertex data from the raw struct, expanding the local AABB
    // to include each vertex.
    for (int vNum = 0; vNum < nVerts; ++vNum) {

    	// Get the vertex position and colour
		Vertex3f vertex(PicoGetSurfaceXYZ(surf, vNum));

		// Expand the AABB to include this new vertex
    	_localAABB.includePoint(vertex);

    	_vertices[vNum].vertex = vertex;
    	_vertices[vNum].normal = Normal3f(PicoGetSurfaceNormal(surf, vNum));
    	_vertices[vNum].texcoord = TexCoord2f(PicoGetSurfaceST(surf, 0, vNum));
    	_vertices[vNum].colour =
    		getColourVector(PicoGetSurfaceColor(surf, 0, vNum));
    }

    // Stream in the index data
    picoIndex_t* ind = PicoGetSurfaceIndexes(surf, 0);
    for (unsigned int i = 0; i < _nIndices; i++)
    	_indices[i] = ind[i];

	// Calculate the tangent and bitangent vectors
	calculateTangents();

	// Construct the DLs
	createDisplayLists();
}
예제 #8
0
void recalculateTangentsT(scene::IMeshBuffer* buffer, bool recalculate_normals, bool smooth, bool angle_weighted)
{
    if (!buffer || (buffer->getVertexType() != video::EVT_TANGENTS))
        return;

    const u32 vtxCnt = buffer->getVertexCount();
    const u32 idxCnt = buffer->getIndexCount();

    T* idx = reinterpret_cast<T*>(buffer->getIndices());
    video::S3DVertexTangents* v =
        (video::S3DVertexTangents*)buffer->getVertices();

    if (smooth)
    {
        u32 i;

        for (i = 0; i != vtxCnt; ++i)
        {
            if (recalculate_normals)
                v[i].Normal.set(0.f, 0.f, 0.f);
            v[i].Tangent.set(0.f, 0.f, 0.f);
            v[i].Binormal.set(0.f, 0.f, 0.f);
        }

        //Each vertex gets the sum of the tangents and binormals from the faces around it
        for (i = 0; i<idxCnt; i += 3)
        {
            // if this triangle is degenerate, skip it!
            if (v[idx[i + 0]].Pos == v[idx[i + 1]].Pos ||
                v[idx[i + 0]].Pos == v[idx[i + 2]].Pos ||
                v[idx[i + 1]].Pos == v[idx[i + 2]].Pos
                /*||
                v[idx[i+0]].TCoords == v[idx[i+1]].TCoords ||
                v[idx[i+0]].TCoords == v[idx[i+2]].TCoords ||
                v[idx[i+1]].TCoords == v[idx[i+2]].TCoords */
                )
                continue;

            //Angle-weighted normals look better, but are slightly more CPU intensive to calculate
            core::vector3df weight(1.f, 1.f, 1.f);
            if (angle_weighted)
                weight = getAngleWeight(v[i + 0].Pos, v[i + 1].Pos, v[i + 2].Pos);
            core::vector3df localNormal;
            core::vector3df localTangent;
            core::vector3df localBinormal;

            calculateTangents(
                localNormal,
                localTangent,
                localBinormal,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].TCoords,
                v[idx[i + 1]].TCoords,
                v[idx[i + 2]].TCoords);

            if (recalculate_normals)
                v[idx[i + 0]].Normal += localNormal * weight.X;
            v[idx[i + 0]].Tangent += localTangent * weight.X;
            v[idx[i + 0]].Binormal += localBinormal * weight.X;

            calculateTangents(
                localNormal,
                localTangent,
                localBinormal,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].TCoords,
                v[idx[i + 2]].TCoords,
                v[idx[i + 0]].TCoords);

            if (recalculate_normals)
                v[idx[i + 1]].Normal += localNormal * weight.Y;
            v[idx[i + 1]].Tangent += localTangent * weight.Y;
            v[idx[i + 1]].Binormal += localBinormal * weight.Y;

            calculateTangents(
                localNormal,
                localTangent,
                localBinormal,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].TCoords,
                v[idx[i + 0]].TCoords,
                v[idx[i + 1]].TCoords);

            if (recalculate_normals)
                v[idx[i + 2]].Normal += localNormal * weight.Z;
            v[idx[i + 2]].Tangent += localTangent * weight.Z;
            v[idx[i + 2]].Binormal += localBinormal * weight.Z;
        }

        // Normalize the tangents and binormals
        if (recalculate_normals)
        {
            for (i = 0; i != vtxCnt; ++i)
                v[i].Normal.normalize();
        }
        for (i = 0; i != vtxCnt; ++i)
        {
            v[i].Tangent.normalize();
            v[i].Binormal.normalize();
        }
    }
    else
    {
        core::vector3df localNormal;
        for (u32 i = 0; i<idxCnt; i += 3)
        {
            calculateTangents(
                localNormal,
                v[idx[i + 0]].Tangent,
                v[idx[i + 0]].Binormal,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].TCoords,
                v[idx[i + 1]].TCoords,
                v[idx[i + 2]].TCoords);
            if (recalculate_normals)
                v[idx[i + 0]].Normal = localNormal;

            calculateTangents(
                localNormal,
                v[idx[i + 1]].Tangent,
                v[idx[i + 1]].Binormal,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].TCoords,
                v[idx[i + 2]].TCoords,
                v[idx[i + 0]].TCoords);
            if (recalculate_normals)
                v[idx[i + 1]].Normal = localNormal;

            calculateTangents(
                localNormal,
                v[idx[i + 2]].Tangent,
                v[idx[i + 2]].Binormal,
                v[idx[i + 2]].Pos,
                v[idx[i + 0]].Pos,
                v[idx[i + 1]].Pos,
                v[idx[i + 2]].TCoords,
                v[idx[i + 0]].TCoords,
                v[idx[i + 1]].TCoords);
            if (recalculate_normals)
                v[idx[i + 2]].Normal = localNormal;
        }
    }
}
예제 #9
0
	void MeshUtility::calculateTangentSpace(Vector3* vertices, Vector2* uv, UINT8* indices, UINT32 numVertices,
		UINT32 numIndices, Vector3* normals, Vector3* tangents, Vector3* bitangents, UINT32 indexSize)
	{
		calculateNormals(vertices, indices, numVertices, numIndices, normals, indexSize);
		calculateTangents(vertices, normals, uv, indices, numVertices, numIndices, tangents, bitangents, indexSize);
	}
예제 #10
0
uint32_t objToBin(const uint8_t* _objData
                  , bx::WriterSeekerI* _writer
                  , uint32_t _packUv
                  , uint32_t _packNormal
                  , bool _ccw
                  , bool _flipV
                  , bool _hasTangent
                  , float _scale
                 )
{
    int64_t parseElapsed = -bx::getHPCounter();
    int64_t triReorderElapsed = 0;

    const int64_t begin = _writer->seek();

    Vector3Array positions;
    Vector3Array normals;
    Vector3Array texcoords;
    Index3Map indexMap;
    TriangleArray triangles;
    BgfxGroupArray groups;

    uint32_t num = 0;

    MeshGroup group;
    group.m_startTriangle = 0;
    group.m_numTriangles = 0;
    group.m_name = "";
    group.m_material = "";

    char commandLine[2048];
    uint32_t len = sizeof(commandLine);
    int argc;
    char* argv[64];
    const char* next = (const char*)_objData;
    do
    {
        next = bx::tokenizeCommandLine(next, commandLine, len, argc, argv, BX_COUNTOF(argv), '\n');
        if (0 < argc)
        {
            if (0 == strcmp(argv[0], "#") )
            {
                if (2 < argc
                        &&  0 == strcmp(argv[2], "polygons") )
                {
                }
            }
            else if (0 == strcmp(argv[0], "f") )
            {
                Triangle triangle;
                memset(&triangle, 0, sizeof(Triangle) );

                const int numNormals   = (int)normals.size();
                const int numTexcoords = (int)texcoords.size();
                const int numPositions = (int)positions.size();
                for (uint32_t edge = 0, numEdges = argc-1; edge < numEdges; ++edge)
                {
                    Index3 index;
                    index.m_texcoord = 0;
                    index.m_normal = 0;
                    index.m_vertexIndex = -1;

                    char* vertex = argv[edge+1];
                    char* texcoord = strchr(vertex, '/');
                    if (NULL != texcoord)
                    {
                        *texcoord++ = '\0';

                        char* normal = strchr(texcoord, '/');
                        if (NULL != normal)
                        {
                            *normal++ = '\0';
                            const int nn = atoi(normal);
                            index.m_normal = (nn < 0) ? nn+numNormals : nn-1;
                        }

                        const int tex = atoi(texcoord);
                        index.m_texcoord = (tex < 0) ? tex+numTexcoords : tex-1;
                    }

                    const int pos = atoi(vertex);
                    index.m_position = (pos < 0) ? pos+numPositions : pos-1;

                    uint64_t hash0 = index.m_position;
                    uint64_t hash1 = uint64_t(index.m_texcoord)<<20;
                    uint64_t hash2 = uint64_t(index.m_normal)<<40;
                    uint64_t hash = hash0^hash1^hash2;

                    CS_STL::pair<Index3Map::iterator, bool> result = indexMap.insert(CS_STL::make_pair(hash, index) );
                    if (!result.second)
                    {
                        Index3& oldIndex = result.first->second;
                        BX_UNUSED(oldIndex);
                        BX_CHECK(oldIndex.m_position == index.m_position
                                 && oldIndex.m_texcoord == index.m_texcoord
                                 && oldIndex.m_normal == index.m_normal
                                 , "Hash collision!"
                                );
                    }

                    switch (edge)
                    {
                    case 0:
                    case 1:
                    case 2:
                        triangle.m_index[edge] = hash;
                        if (2 == edge)
                        {
                            if (_ccw)
                            {
                                std::swap(triangle.m_index[1], triangle.m_index[2]);
                            }
                            triangles.push_back(triangle);
                        }
                        break;

                    default:
                        if (_ccw)
                        {
                            triangle.m_index[2] = triangle.m_index[1];
                            triangle.m_index[1] = hash;
                        }
                        else
                        {
                            triangle.m_index[1] = triangle.m_index[2];
                            triangle.m_index[2] = hash;
                        }
                        triangles.push_back(triangle);
                        break;
                    }
                }
            }
            else if (0 == strcmp(argv[0], "g") )
            {
                if (1 >= argc)
                {
                    CS_PRINT("Error parsing *.obj file.\n");
                    return 0;
                }
                group.m_name = argv[1];
            }
            else if (*argv[0] == 'v')
            {
                group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
                if (0 < group.m_numTriangles)
                {
                    groups.push_back(group);
                    group.m_startTriangle = (uint32_t)(triangles.size() );
                    group.m_numTriangles = 0;
                }

                if (0 == strcmp(argv[0], "vn") )
                {
                    Vector3 normal;
                    normal.x = (float)atof(argv[1]);
                    normal.y = (float)atof(argv[2]);
                    normal.z = (float)atof(argv[3]);

                    normals.push_back(normal);
                }
                else if (0 == strcmp(argv[0], "vp") )
                {
                    static bool once = true;
                    if (once)
                    {
                        once = false;
                        CS_PRINT("warning: 'parameter space vertices' are unsupported.\n");
                    }
                }
                else if (0 == strcmp(argv[0], "vt") )
                {
                    Vector3 texcoord;
                    texcoord.x = (float)atof(argv[1]);
                    texcoord.y = 0.0f;
                    texcoord.z = 0.0f;
                    switch (argc)
                    {
                    case 4:
                        texcoord.z = (float)atof(argv[3]);
                    // fallthrough
                    case 3:
                        texcoord.y = (float)atof(argv[2]);
                        break;

                    default:
                        break;
                    }

                    texcoords.push_back(texcoord);
                }
                else
                {
                    float px = (float)atof(argv[1]);
                    float py = (float)atof(argv[2]);
                    float pz = (float)atof(argv[3]);
                    float pw = 1.0f;
                    if (argc > 4)
                    {
                        pw = (float)atof(argv[4]);
                    }

                    float invW = _scale/pw;
                    px *= invW;
                    py *= invW;
                    pz *= invW;

                    Vector3 pos;
                    pos.x = px;
                    pos.y = py;
                    pos.z = pz;

                    positions.push_back(pos);
                }
            }
            else if (0 == strcmp(argv[0], "usemtl") )
            {
                std::string material(argv[1]);

                if (material != group.m_material)
                {
                    group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
                    if (0 < group.m_numTriangles)
                    {
                        groups.push_back(group);
                        group.m_startTriangle = (uint32_t)(triangles.size() );
                        group.m_numTriangles = 0;
                    }
                }

                group.m_material = material;
            }
// unsupported tags
//              else if (0 == strcmp(argv[0], "mtllib") )
//              {
//              }
//              else if (0 == strcmp(argv[0], "o") )
//              {
//              }
//              else if (0 == strcmp(argv[0], "s") )
//              {
//              }
        }

        ++num;
    }
    while ('\0' != *next);

    group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
    if (0 < group.m_numTriangles)
    {
        groups.push_back(group);
        group.m_startTriangle = (uint32_t)(triangles.size() );
        group.m_numTriangles = 0;
    }

    int64_t now = bx::getHPCounter();
    parseElapsed += now;
    int64_t convertElapsed = -now;

    std::sort(groups.begin(), groups.end(), GroupSortByMaterial() );

    bool hasColor = false;
    bool hasNormal;
    bool hasTexcoord;
    {
        Index3Map::const_iterator it = indexMap.begin();
        hasNormal   = 0 != it->second.m_normal;
        hasTexcoord = 0 != it->second.m_texcoord;

        if (!hasTexcoord
                &&  texcoords.size() == positions.size() )
        {
            hasTexcoord = true;

            for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
            {
                it->second.m_texcoord = it->second.m_position;
            }
        }

        if (!hasNormal
                &&  normals.size() == positions.size() )
        {
            hasNormal = true;

            for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
            {
                it->second.m_normal = it->second.m_position;
            }
        }
    }

    bgfx::VertexDecl decl;
    decl.begin();
    decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);

    if (hasColor)
    {
        decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
    }

    if (hasTexcoord)
    {
        switch (_packUv)
        {
        default:
        case 0:
            decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
            break;

        case 1:
            decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
            break;
        }
    }

    if (hasNormal)
    {
        _hasTangent &= hasTexcoord;

        switch (_packNormal)
        {
        default:
        case 0:
            decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
            if (_hasTangent)
            {
                decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Float);
            }
            break;

        case 1:
            decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
            if (_hasTangent)
            {
                decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
            }
            break;
        }
    }
    decl.end();

    uint32_t stride = decl.getStride();
    uint8_t* vertexData = new uint8_t[triangles.size() * 3 * stride];
    uint16_t* indexData = new uint16_t[triangles.size() * 3];
    int32_t numVertices = 0;
    int32_t numIndices = 0;
    int32_t numPrimitives = 0;

    uint8_t* vertices = vertexData;
    uint16_t* indices = indexData;

    std::string material = groups.begin()->m_material;

    BgfxPrimitiveArray primitives;

    Primitive prim;
    prim.m_startVertex = 0;
    prim.m_startIndex  = 0;

    uint32_t positionOffset = decl.getOffset(bgfx::Attrib::Position);
    uint32_t color0Offset   = decl.getOffset(bgfx::Attrib::Color0);

    uint32_t ii = 0;
    for (BgfxGroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii)
    {
        for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri)
        {
            if (material != groupIt->m_material
                    ||  65533 < numVertices)
            {
                prim.m_numVertices = numVertices - prim.m_startVertex;
                prim.m_numIndices = numIndices - prim.m_startIndex;
                if (0 < prim.m_numVertices)
                {
                    primitives.push_back(prim);
                }

                triReorderElapsed -= bx::getHPCounter();
                for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
                {
                    const Primitive& prim = *primIt;
                    triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
                }
                triReorderElapsed += bx::getHPCounter();

                if (_hasTangent)
                {
                    calculateTangents(vertexData, numVertices, decl, indexData, numIndices);
                }

                write(_writer
                      , vertexData
                      , numVertices
                      , decl
                      , indexData
                      , numIndices
                      , material.c_str()
                      , primitives.data()
                      , (uint32_t)primitives.size()
                     );
                primitives.clear();

                for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt)
                {
                    indexIt->second.m_vertexIndex = -1;
                }

                vertices = vertexData;
                indices = indexData;
                numVertices = 0;
                numIndices = 0;
                prim.m_startVertex = 0;
                prim.m_startIndex = 0;
                ++numPrimitives;

                material = groupIt->m_material;
            }

            Triangle& triangle = triangles[tri];
            for (uint32_t edge = 0; edge < 3; ++edge)
            {
                uint64_t hash = triangle.m_index[edge];
                Index3& index = indexMap[hash];
                if (index.m_vertexIndex == -1)
                {
                    index.m_vertexIndex = numVertices++;

                    float* position = (float*)(vertices + positionOffset);
                    memcpy(position, &positions[index.m_position], 3*sizeof(float) );

                    if (hasColor)
                    {
                        uint32_t* color0 = (uint32_t*)(vertices + color0Offset);
                        *color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff);
                    }

                    if (hasTexcoord)
                    {
                        float uv[2];
                        memcpy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );

                        if (_flipV)
                        {
                            uv[1] = -uv[1];
                        }

                        bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices);
                    }

                    if (hasNormal)
                    {
                        float normal[4];
                        bx::vec3Norm(normal, (float*)&normals[index.m_normal]);
                        bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices);
                    }

                    vertices += stride;
                }

                *indices++ = (uint16_t)index.m_vertexIndex;
                ++numIndices;
            }
        }

        if (0 < numVertices)
        {
            prim.m_numVertices = numVertices - prim.m_startVertex;
            prim.m_numIndices = numIndices - prim.m_startIndex;
            bx::strlcpy(prim.m_name, groupIt->m_name.c_str(), 128);
            primitives.push_back(prim);
            prim.m_startVertex = numVertices;
            prim.m_startIndex = numIndices;
        }

        //CS_PRINT("%3d: s %5d, n %5d, %s\n"
        //    , ii
        //    , groupIt->m_startTriangle
        //    , groupIt->m_numTriangles
        //    , groupIt->m_material.c_str()
        //    );
    }

    if (0 < primitives.size() )
    {
        triReorderElapsed -= bx::getHPCounter();
        for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
        {
            const Primitive& prim = *primIt;
            triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
        }
        triReorderElapsed += bx::getHPCounter();

        if (_hasTangent)
        {
            calculateTangents(vertexData, numVertices, decl, indexData, numIndices);
        }

        write(_writer, vertexData, numVertices, decl, indexData, numIndices, material.c_str(), primitives.data(), (uint32_t)primitives.size());
    }

    delete [] indexData;
    delete [] vertexData;

    now = bx::getHPCounter();
    convertElapsed += now;

    const int64_t end = _writer->seek();
    const uint32_t dataSize = uint32_t(end-begin);
    CS_PRINT("size: %u\n", dataSize);

    CS_PRINT("parse %f [s]\ntri reorder %f [s]\nconvert %f [s]\n# %d, g %d, p %d, v %d, i %d\n"
             , double(parseElapsed)/bx::getHPFrequency()
             , double(triReorderElapsed)/bx::getHPFrequency()
             , double(convertElapsed)/bx::getHPFrequency()
             , num
             , uint32_t(groups.size() )
             , numPrimitives
             , numVertices
             , numIndices
            );

    return dataSize;
}
예제 #11
0
	void Mesh::createCylinder(Number height, Number radius, int numSegments, bool capped) {
	
		setMeshType(Mesh::TRI_MESH);
		Number lastx = 0;
		Number lastz = 0;
		Number lastv = 0;		
		for (int i=0 ; i < numSegments+1; i++) {
			Number v = ((Number)i)/((Number)numSegments);
			Number pos = ((PI*2.0)/((Number)numSegments)) * i;
			Number x = sin(pos) * radius;
			Number z = cos(pos) * radius;
			
			if(i > 0) {
				Polygon *polygon = new Polygon();
				polygon->addVertex(lastx,0,lastz,lastv,0);				
				polygon->addVertex(x,0,z, v, 0);
				polygon->addVertex(x,height,z, v, 1);				
				addPolygon(polygon);							

				polygon = new Polygon();	
				polygon->addVertex(x,height,z, v, 1);							
				polygon->addVertex(lastx,height,lastz, lastv, 1);
				polygon->addVertex(lastx,0,lastz,lastv,0);												
				addPolygon(polygon);	
				
				if(capped) {
				polygon = new Polygon();	
				polygon->addVertex(lastx,height,lastz, 0.5+(lastz/radius*0.5), 0.5+(lastx/radius*0.5));			
				polygon->addVertex(x,height,z, 0.5+(z/radius*0.5), 0.5+(x/radius*0.5));														
				polygon->addVertex(0,height,0,0.5,0.5);							
				addPolygon(polygon);			

				polygon = new Polygon();	
				polygon->addVertex(lastx,0,lastz, 0.5+(lastz/radius*0.5), 0.5+(lastx/radius*0.5));						
				polygon->addVertex(0,0,0,0.5,0.5);																																					
				polygon->addVertex(x,0,z, 0.5+(z/radius*0.5), 0.5+(x/radius*0.5));								
				addPolygon(polygon);			
				}
								
			}
			lastx = x;
			lastz = z;			
			lastv = v;
		/*
			Polygon *polygon = new Polygon();
			polygon->addVertex(w,0,h, 1, 1);
			polygon->addVertex(0,0,h, 1, 0);
			polygon->addVertex(0,0,0,0,0);
			polygon->addVertex(w,0,0,0,1);
			addPolygon(polygon);			
			*/
        }
		
		for(int i=0; i < polygons.size(); i++) {
			for(int j=0; j < polygons[i]->getVertexCount(); j++) {
//				polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - (radius/2.0f);
				polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - (height/2.0f);
//				polygons[i]->getVertex(j)->z = polygons[i]->getVertex(j)->z - (radius/2.0f);	
			}
		}
		
		
		calculateNormals();
		calculateTangents();
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;										
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;		
	}
예제 #12
0
	void Mesh::createTorus(Number radius, Number tubeRadius, int rSegments, int tSegments) {
	
		setMeshType(Mesh::TRI_MESH);
			
		Vector3 **grid = (Vector3 **) malloc(sizeof(Vector3*) * rSegments);
		for (int i=0 ; i < rSegments; i++) {
			grid[i] = (Vector3*) malloc(sizeof(Vector3) * tSegments);		
		}
		
		for (int i=0 ; i < rSegments; i++) {
			for (int j = 0; j < tSegments; ++j) {
				Number u = ((Number)i) / rSegments * 2.0 * PI;
				Number v = ((Number)j) / tSegments * 2.0 * PI;	

				grid[i][j] = Vector3((radius + tubeRadius*cos(v))*cos(u), tubeRadius*sin(v), (radius + tubeRadius*cos(v))*sin(u));							
													
			}
		}	
		
		for (int i=0 ; i < rSegments; i++) {
			for (int j = 0; j < tSegments; ++j) {

				int ip = (i+1) % rSegments;
				int jp = (j+1) % tSegments;
					
				Vector3 a = grid[i ][j];
				Vector3 b = grid[ip][j];
				Vector3 c = grid[i ][jp];
				Vector3 d = grid[ip][jp];

				Vector2 uva = Vector2(((Number)i)     / ((Number)rSegments), ((Number)j)     / ((Number)tSegments));
				Vector2 uvb = Vector2((((Number)i)+1.0) / ((Number)rSegments), ((Number)j)     / ((Number)tSegments));
				Vector2 uvc = Vector2(((Number)i)    / ((Number)rSegments), (((Number)j)+1.0) / ((Number)tSegments));
				Vector2 uvd = Vector2((((Number)i)+1.0) / ((Number)rSegments), (((Number)j)+1.0) / ((Number)tSegments));


				Polygon *polygon = new Polygon();
				polygon->addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
				polygon->addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);							
				polygon->addVertex(a.x, a.y, a.z, uva.x ,uva.y);
				addPolygon(polygon);	

				polygon = new Polygon();
				polygon->addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);
				polygon->addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);					
				polygon->addVertex(d.x, d.y, d.z, uvd.x ,uvd.y);				
				addPolygon(polygon);	
			}
		}
		
		for (int i=0 ; i < rSegments; i++) {
			free(grid[i]);
		}		
		free(grid);
		
	
		calculateNormals();
		calculateTangents();
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;										
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;				
	}
예제 #13
0
	void Mesh::createSphere(Number _radius, int _segmentsH, int _segmentsW) {

		setMeshType(Mesh::TRI_MESH);


		Vector3 **grid = (Vector3 **) malloc(sizeof(Vector3*) * (_segmentsH+1));
		for (int i=0 ; i < _segmentsH+1; i++) {
			grid[i] = (Vector3*) malloc(sizeof(Vector3) * _segmentsW+1);		
		}
		
	
		for (int i = 0; i < _segmentsW; i++) {
			grid[0][i] = Vector3(0,-_radius,0);
		}
			
		for (int j = 1; j < _segmentsH; j++) {
			Number horangle = ((float)j) / ((float)_segmentsH) * PI;
			Number z = -_radius * cos(horangle);
			Number ringradius = _radius * sin(horangle);

			for (int i = 0; i < _segmentsW; i++) {
				Number verangle = 2.0 * ((float)i) / ((float)_segmentsW) * PI;
				Number x = ringradius * sin(verangle);
				Number y = ringradius * cos(verangle);
				grid[j][i] = Vector3(y, z, x);
            }
		}

		for (int i = 0; i < _segmentsW; i++) {
                grid[_segmentsH][i] = Vector3(0,_radius, 0);
		}

		for (int j = 1; j <= _segmentsH; j++) {
			for (int i = 0; i < _segmentsW; i++) {
				Vector3 a = grid[j][i];
				Vector3 b = grid[j][(i-1+_segmentsW) % _segmentsW];
				Vector3 c = grid[j-1][(i-1+_segmentsW) % _segmentsW];
				Vector3 d = grid[j-1][i];

				int i2 = i;
				if (i == 0) i2 = _segmentsW;

				Number vab = ((float)j) / ((float)_segmentsH);
				Number vcd = (((float)j)-1.0) / ((float)_segmentsH);
				Number uad = ((float)i2) / ((float)_segmentsW);
				Number ubc = (((float)i2)-1.0) / ((float)_segmentsW);
				Vector2 uva = Vector2(uad,vab);
				Vector2 uvb = Vector2(ubc,vab);
				Vector2 uvc = Vector2(ubc,vcd);
				Vector2 uvd = Vector2(uad,vcd);

				if (j < _segmentsH) {
					Polygon *polygon = new Polygon();
					polygon->addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
					polygon->addVertex(b.x, b.y, b.z, uvb.x ,uvb.y);							
					polygon->addVertex(a.x, a.y, a.z, uva.x ,uva.y);
					addPolygon(polygon);								
				}
				if (j > 1) {
					Polygon *polygon = new Polygon();
					polygon->addVertex(d.x, d.y, d.z, uvd.x ,uvd.y);												
					polygon->addVertex(c.x, c.y, c.z, uvc.x ,uvc.y);
					polygon->addVertex(a.x, a.y, a.z, uva.x ,uva.y);
					addPolygon(polygon);					
				}
			}
		}

		calculateNormals();
		calculateTangents();
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;										
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;		
	}
예제 #14
0
	void Mesh::loadFromFile(OSFILE *inFile) {

		unsigned int meshType;		
		OSBasics::read(&meshType, sizeof(unsigned int), 1, inFile);				
		setMeshType(meshType);
		
		int verticesPerFace;
		switch(meshType) {
			case TRI_MESH:
				verticesPerFace = 3;
			break;
			case QUAD_MESH:
				verticesPerFace = 4;
			break;
			default:
				verticesPerFace = 1;				
			break;
		}
		
		unsigned int numFaces;		
		OSBasics::read(&numFaces, sizeof(unsigned int), 1, inFile);
		
		Vector3_struct pos;
		Vector3_struct nor;
		Vector4_struct col;			
		Vector2_struct tex;
		
		for(int i=0; i < numFaces; i++) {	
			Polygon *poly = new Polygon();			
			
			for(int j=0; j < verticesPerFace; j++) {
				OSBasics::read(&pos, sizeof(Vector3_struct), 1, inFile);
				OSBasics::read(&nor, sizeof(Vector3_struct), 1, inFile);
				OSBasics::read(&col, sizeof(Vector4_struct), 1, inFile);						
				OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);						
				
				Vertex *vertex = new Vertex(pos.x, pos.y, pos.z);
				vertex->setNormal(nor.x,nor.y, nor.z);
				vertex->restNormal.set(nor.x,nor.y, nor.z);
				vertex->vertexColor.setColor(col.x,col.y, col.z, col.w);
				vertex->setTexCoord(tex.x, tex.y);
				
				unsigned int numBoneWeights;
				OSBasics::read(&numBoneWeights, sizeof(unsigned int), 1, inFile);								
				for(int b=0; b < numBoneWeights; b++) {
					float weight;
					unsigned int boneID;
					OSBasics::read(&boneID, sizeof(unsigned int), 1, inFile);													
					OSBasics::read(&weight, sizeof(float), 1, inFile);																		
					vertex->addBoneAssignment(boneID, weight);
				}
				
				Number totalWeight = 0;				
				for(int m=0; m < vertex->getNumBoneAssignments(); m++) {
					BoneAssignment *ba = vertex->getBoneAssignment(m);					
					totalWeight += ba->weight;
				}				

				for(int m=0; m < vertex->getNumBoneAssignments(); m++) {
					BoneAssignment *ba = vertex->getBoneAssignment(m);					
					ba->weight = ba->weight/totalWeight;
				}				

				
				poly->addVertex(vertex);
			}
			addPolygon(poly);
		}
		
		calculateTangents();
		
		arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
		arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
		arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
		arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;	
		arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;								
	}