示例#1
0
void optimizePostTLTipsify(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size, std::vector<unsigned int>* clusters)
{
	tipsify(destination, indices, index_count, vertex_count, cache_size, clusters);
}
示例#2
0
json WebMesh::processOneShape(tinyobj::shape_t currShape, 
                        vector<int>& vertices_to_write, 
                        vector<int>& indices_to_write) {

    vector<Vertex*> origVertices;
    vector<int> origIndices;
    int needReconstructNormals = readShapeMesh(currShape.mesh, origVertices, origIndices);


    //STEP 2 (optional): reorder indices,
    vector<int> reorder_indices;
    if (m_triOrdering == TriangleReordering::TIPSIFY) {
        int* tip = (int*)tipsify(&origIndices[0], origIndices.size()/3, origVertices.size(), 120);
        reorder_indices.assign(tip, tip+origIndices.size());
    }
    else if (m_triOrdering == TriangleReordering::FORSYTH) {
        int *forth = (int *) reorderForsyth(&origIndices[0], origIndices.size() / 3, origVertices.size());
        reorder_indices.assign(forth, forth + origIndices.size());
    }
    else
        reorder_indices = origIndices;


    //get AABB
    AABB* aabb = Geo::getAABB(origVertices);


    //STEP 4: Quantize vertices - option to encode per axis or straight
    vector<Vertex*> quantizedVertices;
    vector<int> out_m_bV;
    generateQuantizedVertices(origVertices, aabb, m_bV, m_bN, m_bT,
                              quantizedVertices, m_vertexQuantization,
                              out_m_bV, m_fibLevels);

    //STEP 4a: Remove duplicate verts and triangles from quantization process
    vector<Vertex*> dupVerts;
    vector<int> dupInds;
    removeDuplicateVertices(quantizedVertices,
                            dupVerts,
                            reorder_indices,
                            dupInds);

        //STEP 5: Reindex mesh for index compression
    map<Vertex, int> vertex_int_map;
    vector<Vertex*> FINAL_VERTICES;
    vector<int> reIndexed_inds;

    cout << "Reindexing..." << endl;
    //reIndexAccordingToIndices(quantizedVertices, reorder_indices, vertex_int_map, FINAL_VERTICES, reIndexed_inds);
    reIndexAccordingToIndices(dupVerts, dupInds, vertex_int_map, FINAL_VERTICES, reIndexed_inds);



    //we store the final number of faces here, before we compress index buffer
    int finalNumFaces = dupInds.size()/3;

    //STEP 6 (optional): COMPRESS INDICES
    vector<int> FINAL_INDICES;
    int max_step = 1;
    if (m_indCompression == IndexCompression::PAIRED_TRIS) {
        cout << "Compressing indices..." << endl;
        Geo::compressIndexBuffer(reIndexed_inds, FINAL_INDICES);
        max_step = 3;
    }
    else
        FINAL_INDICES = reIndexed_inds;



    //STEP 6: Encode everythings, either delta or HWM 
    cout << "Encoding..." << endl;

    deltaEncodeVertices(FINAL_VERTICES, vertices_to_write, m_bT, m_normalEncoding);

    int fourByters = 0;

    if (m_indCoding == IndexCoding::DELTA){
        fourByters = encodeIndicesDelta(FINAL_INDICES, indices_to_write);
    }
    else {

        if (m_meshEncoding == MeshEncoding::UTF)
            fourByters = encodeIndicesHighWater(FINAL_INDICES, indices_to_write, max_step, true); //true says its UTF safe
        else
            encodeIndicesHighWater(FINAL_INDICES, indices_to_write, max_step, false); //true says its UTF safe
    }

    //write metadata
    json metadata = writeHeader(vertices_to_write,
            indices_to_write,
            aabb,
            int(FINAL_VERTICES.size()),
            finalNumFaces,
            fourByters,
            max_step,
            currShape.mesh.material_ids[0],
            currShape.name.c_str(),
            needReconstructNormals,
            out_m_bV[0], out_m_bV[1], out_m_bV[2]);
    return metadata;

}
cGeometry *cManagerObjectLoader::loadDaeGeometry(const eiString& srcFile) {
	if(!cFileParser::isFileExists(srcFile)) {
		ManagerReporter.print("Can't load Dae Geometry: " + srcFile);
		return NULL;
	}
	Assimp::Importer importer;

	// read up dae scene
	char ansiSrcFile[EIString_STACK_SIZE];
	srcFile.toAnsiChar(ansiSrcFile, EIString_STACK_SIZE);
	const const aiScene* scene = importer.ReadFile(ansiSrcFile,(aiProcessPreset_TargetRealtime_Quality | aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder)^aiProcess_FindInvalidData);
	if(scene == NULL)
		return 0;

	int nVertex = 0;
	int nIndex = 0;
	int nMeshes = scene->mNumMeshes;
	aiMesh** meshes = scene->mMeshes;

	for(uint32 i = 0; i < nMeshes; i++) {
		aiMesh *mesh = meshes[i];
		nVertex += mesh->mNumVertices;
		nIndex += mesh->mNumFaces * 3;
	}

	// read up vertex + index
	//tVertexLayouts::tVertexNro::vertex* vertices = new tVertexLayouts::tVertexNro::vertex[nVertex];
	eiFloat3 *verticesPos = new eiFloat3[nVertex];
	uint32 *indices = new uint32[nIndex];
	int indexI = 0;
	int vertexI = 0;
	int vertexOffset = 0;
	for(uint32 i = 0; i < nMeshes;i++) {
		aiMesh* mesh = meshes[i];
		aiVector3D* currVertices	= mesh->mVertices;
		//aiVector3D* currNormals		= mesh->mNormals;
		//aiVector3D* currTangents	= mesh->mTangents;
		//aiVector3D* currTxcoords	= mesh->mTextureCoords[0]; // @TODO not general algorithm, wee need to handle more UV channels


		// read indices
		aiFace* faces = mesh->mFaces;
		int nFaces = mesh->mNumFaces;
		for(uint32 j = 0; j < nFaces; indexI += 3, j++) {
			aiFace& face = faces[j];

			indices[indexI]		= face.mIndices[0] + vertexI; // each mesh start indexing from 0 in .dae r
			indices[indexI + 1]	= face.mIndices[1] + vertexI;
			indices[indexI + 2]	= face.mIndices[2] + vertexI;
		}

		// read vertex transforms
		aiNode *root = scene->mRootNode;
		bool meshHaveBakedTrans = true;
		if(strcmp(root->mName.C_Str(),"RootNode") == 0)
			meshHaveBakedTrans = false;

		aiVector3D scaling(1.0f, 1.0f, 1.0f);
		aiQuaternion rotation(1.0f, 0.0f, 0.0f, 0.0f);
		aiVector3D position(0.0f, 0.0f, 0.0f);

		if(!meshHaveBakedTrans) {
			aiMatrix4x4 meshTrans;
			aiNode *meshTransNode = scene->mRootNode->mChildren[i];
			if(scene->mRootNode->mNumChildren > i) {
				meshTrans *= meshTransNode->mTransformation;
				if(meshTransNode->mNumChildren > 0)
					meshTrans *= meshTransNode->mChildren[0]->mTransformation;
			}
			meshTrans.Decompose(scaling, rotation, position);
			position.y *= -1;
			//position.z *= -1;
			eiSwap(position.y, position.z);
		} else {
			//-
			aiNode *rootNode = scene->mRootNode;
			aiNode *meshTransNode = (scene->mRootNode->mNumChildren > 1) ? rootNode->mChildren[1] : rootNode->mChildren[0];

			aiMatrix4x4 meshTrans = meshTransNode->mTransformation;
			if(meshTransNode->mNumChildren >0) {
				meshTrans *= meshTransNode->mChildren[0]->mTransformation;
				if(meshTransNode->mChildren[0]->mNumChildren > 0)
					meshTrans *= meshTransNode->mChildren[0]->mChildren[0]->mTransformation;
			}
			
			meshTrans.Decompose(scaling, rotation, position);
		}

		

		// process transform for vertices, normals, tangents, read them
		for(uint32 j = 0; j < mesh->mNumVertices; vertexI++, j++) {
			aiVector3D pos = rotation.Rotate(currVertices[j] + position).SymMul(scaling);

			/*aiVector3D norm	= rotation.Rotate(currNormals[j]);
			aiVector3D tangent	= rotation.Rotate(currTangents[j]);
			aiVector3D txcoord	= currTxcoords[j];*/
			
			if(meshHaveBakedTrans) {
				eiSwap(pos.y, pos.z);
				// x, z, y  stupid assimp
			}

			if(!meshHaveBakedTrans) {
				pos.y *= -1; // I really don't know why need that
			}
		

			verticesPos[vertexI] = eiFloat3(pos.x, pos.y, pos.z);

			//if(bakedRotation) {
				//verticesPos[vertexI] = eiFloat3(pos.x, pos.z, pos.y);
			//} else {
				//verticesPos[vertexI] = eiFloat3(pos.x, -pos.y, pos.z);
			//}

			/*verticesPos[vertexI]		= eiFloat3(currVertices[j].x, currVertices[j].y, currVertices[j].z);
			vertices[vertexI].normalL	= XMFLOAT3(norm.x, -norm.z, norm.y);
			vertices[vertexI].tangentL	= XMFLOAT3(tangent.x, -tangent.z, tangent.y);
 			vertices[vertexI].tex0		= XMFLOAT2(txcoord.x, txcoord.y);*/
		}
	}
	
	// drop non unique vertices
	eiFloat3* uniqueVertices = new eiFloat3[nVertex];
	int nUniqVertices = 0;
	for(uint32 i = 0; i < nVertex; i++) {
		eiFloat3& v = verticesPos[i];

		bool uniq = true;
		int uniqIndex = -1;
		// check vertex uniquness
		for(uint32 j = 0; j < nUniqVertices; j++) {
			if(uniqueVertices[j] == v) {
				uniq = false;
				uniqIndex = j;
				break;
			}
		}

		int currIndex = nUniqVertices;
		if(uniq) {
			uniqueVertices[nUniqVertices] = v;
			nUniqVertices++;
		} else {
			currIndex = uniqIndex;
		}

		for(uint32 k = 0; k <nIndex; k++)
			if(indices[k] == i)
				indices[k] = currIndex;
	}

	// Finally Index reordering for optimal post vertex cache
	uint32* reorderedIndices = new uint32[nIndex];
	reorderedIndices = tipsify(indices,nIndex/3,nVertex,16);
	delete[] indices;

	eiDebugPrint(_T("ObjectLoader:: SuccessFully loaded object: ") + srcFile);
	return new cGeometry(uniqueVertices, reorderedIndices, nUniqVertices, nIndex);
	//return new cGeometry(verticesPos, indices, nVertex, nIndex); UNOPTIMIZED
}