当前位置: 首页>>代码示例>>C++>>正文


C++ SpatialSort类代码示例

本文整理汇总了C++中SpatialSort的典型用法代码示例。如果您正苦于以下问题:C++ SpatialSort类的具体用法?C++ SpatialSort怎么用?C++ SpatialSort使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了SpatialSort类的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: ai_assert

// ------------------------------------------------------------------------------------------------
// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further
// optimizations (except we're using some nice LUTs). A description of the algorithm can be found
// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface
//
// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's
// expected total runtime complexity. The implementation is able to work in-place on the same
// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate
// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings).
// Previous data is replaced/deleted then.
// ------------------------------------------------------------------------------------------------
void CatmullClarkSubdivider::InternSubdivide (
    const aiMesh* const * smesh,
    size_t nmesh,
    aiMesh** out,
    unsigned int num
    )
{
    ai_assert(NULL != smesh && NULL != out);
    INIT_EDGE_HASH_TEMPORARIES();

    // no subdivision requested or end of recursive refinement
    if (!num) {
        return;
    }

    UIntVector maptbl;
    SpatialSort spatial;

    // ---------------------------------------------------------------------
    // 0. Offset table to index all meshes continuously, generate a spatially
    // sorted representation of all vertices in all meshes.
    // ---------------------------------------------------------------------
    typedef std::pair<unsigned int,unsigned int> IntPair;
    std::vector<IntPair> moffsets(nmesh);
    unsigned int totfaces = 0, totvert = 0;
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];

        spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false);
        moffsets[t] = IntPair(totfaces,totvert);

        totfaces += mesh->mNumFaces;
        totvert  += mesh->mNumVertices;
    }

    spatial.Finalize();
    const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh));


#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx)
#define   FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx)

    // ---------------------------------------------------------------------
    // 1. Compute the centroid point for all faces
    // ---------------------------------------------------------------------
    std::vector<Vertex> centroids(totfaces);
    unsigned int nfacesout = 0;
    for (size_t t = 0, n = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];
        for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n)
        {
            const aiFace& face = mesh->mFaces[i];
            Vertex& c = centroids[n];

            for (unsigned int a = 0; a < face.mNumIndices;++a) {
                c += Vertex(mesh,face.mIndices[a]);
            }

            c /= static_cast<float>(face.mNumIndices);
            nfacesout += face.mNumIndices;
        }
    }

    {
    // we want edges to go away before the recursive calls so begin a new scope
    EdgeMap edges;

    // ---------------------------------------------------------------------
    // 2. Set each edge point to be the average of all neighbouring
    // face points and original points. Every edge exists twice
    // if there is a neighboring face.
    // ---------------------------------------------------------------------
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];

        for (unsigned int i = 0; i < mesh->mNumFaces;++i)   {
            const aiFace& face = mesh->mFaces[i];

            for (unsigned int p =0; p< face.mNumIndices; ++p) {
                const unsigned int id[] = {
                    face.mIndices[p],
                    face.mIndices[p==face.mNumIndices-1?0:p+1]
                };
                const unsigned int mp[] = {
                    maptbl[FLATTEN_VERTEX_IDX(t,id[0])],
                    maptbl[FLATTEN_VERTEX_IDX(t,id[1])]
                };

                Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])];
//.........这里部分代码省略.........
开发者ID:1vanK,项目名称:Urho3D,代码行数:101,代码来源:Subdivision.cpp

示例2: vertexDone


//.........这里部分代码省略.........
		float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
        float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
		float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;

		// tangent points in the direction where to positive X axis of the texture coords would point in model space
		// bitangents points along the positive Y axis of the texture coords, respectively
		aiVector3D tangent, bitangent;
		tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
        tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
        tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
        bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
        bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
        bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;

		// store for every vertex of that face
		for( unsigned int b = 0; b < face.mNumIndices; b++)
		{
			unsigned int p = face.mIndices[b];

			// project tangent and bitangent into the plane formed by the vertex' normal
			aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
			aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
			localTangent.Normalize(); localBitangent.Normalize();

			// and write it into the mesh.
			meshTang[p] = localTangent;
			meshBitang[p] = localBitangent;
		}
    }


	// create a helper to quickly find locally close vertices among the vertex array
	// FIX: check whether we can reuse the SpatialSort of a previous step
	SpatialSort* vertexFinder = NULL;
	SpatialSort  _vertexFinder;
	float posEpsilon;
	if (shared)
	{
		std::vector<std::pair<SpatialSort,float> >* avf;
		shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
		if (avf)
		{
			std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
			vertexFinder = &blubb.first;
			posEpsilon = blubb.second;;
		}
	}
	if (!vertexFinder)
	{
		_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
		vertexFinder = &_vertexFinder;
		posEpsilon = ComputePositionEpsilon(pMesh);
	}
	std::vector<unsigned int> verticesFound;

	const float fLimit = cosf(configMaxAngle); 
	std::vector<unsigned int> closeVertices;

	// in the second pass we now smooth out all tangents and bitangents at the same local position 
	// if they are not too far off.
	for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
	{
		if( vertexDone[a])
			continue;

		const aiVector3D& origPos = pMesh->mVertices[a];
开发者ID:1vanK,项目名称:Urho3DQuake2,代码行数:67,代码来源:CalcTangentsProcess.cpp

示例3: static_assert

// ------------------------------------------------------------------------------------------------
// Unites identical vertices in the given mesh
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
    static_assert( AI_MAX_NUMBER_OF_COLOR_SETS    == 8, "AI_MAX_NUMBER_OF_COLOR_SETS    == 8");
	static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");

    // Return early if we don't have any positions
    if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
        return 0;
    }

    // We'll never have more vertices afterwards.
    std::vector<Vertex> uniqueVertices;
    uniqueVertices.reserve( pMesh->mNumVertices);

    // For each vertex the index of the vertex it was replaced by.
    // Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
    //  whether a new vertex was created for the index (true) or if it was replaced by an existing
    //  unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
    //  branching performance.
    static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
    std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);

    // A little helper to find locally close vertices faster.
    // Try to reuse the lookup table from the last step.
    const static float epsilon = 1e-5f;
    // float posEpsilonSqr;
    SpatialSort* vertexFinder = NULL;
    SpatialSort _vertexFinder;

    typedef std::pair<SpatialSort,float> SpatPair;
    if (shared) {
        std::vector<SpatPair >* avf;
        shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
        if (avf)    {
            SpatPair& blubb = (*avf)[meshIndex];
            vertexFinder  = &blubb.first;
            // posEpsilonSqr = blubb.second;
        }
    }
    if (!vertexFinder)  {
        // bad, need to compute it.
        _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
        vertexFinder = &_vertexFinder;
        // posEpsilonSqr = ComputePositionEpsilon(pMesh);
    }

    // Squared because we check against squared length of the vector difference
    static const float squareEpsilon = epsilon * epsilon;

    // Again, better waste some bytes than a realloc ...
    std::vector<unsigned int> verticesFound;
    verticesFound.reserve(10);

    // Run an optimized code path if we don't have multiple UVs or vertex colors.
    // This should yield false in more than 99% of all imports ...
    const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);

    // Now check each vertex if it brings something new to the table
    for( unsigned int a = 0; a < pMesh->mNumVertices; a++)  {
        // collect the vertex data
        Vertex v(pMesh,a);

        // collect all vertices that are close enough to the given position
        vertexFinder->FindIdenticalPositions( v.position, verticesFound);
        unsigned int matchIndex = 0xffffffff;

        // check all unique vertices close to the position if this vertex is already present among them
        for( unsigned int b = 0; b < verticesFound.size(); b++) {

            const unsigned int vidx = verticesFound[b];
            const unsigned int uidx = replaceIndex[ vidx];
            if( uidx & 0x80000000)
                continue;

            const Vertex& uv = uniqueVertices[ uidx];
            // Position mismatch is impossible - the vertex finder already discarded all non-matching positions

            // We just test the other attributes even if they're not present in the mesh.
            // In this case they're initialized to 0 so the comparison succeeds.
            // By this method the non-present attributes are effectively ignored in the comparison.
            if( (uv.normal - v.normal).SquareLength() > squareEpsilon)
                continue;
            if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
                continue;
            if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
                continue;
            if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
                continue;

            // Usually we won't have vertex colors or multiple UVs, so we can skip from here
            // Actually this increases runtime performance slightly, at least if branch
            // prediction is on our side.
            if (complex){
                // manually unrolled because continue wouldn't work as desired in an inner loop,
                // also because some compilers seem to fail the task. Colors and UV coords
                // are interleaved since the higher entries are most likely to be
                // zero and thus useless. By interleaving the arrays, vertices are,
                // on average, rejected earlier.
//.........这里部分代码省略.........
开发者ID:Kvalme,项目名称:assimp,代码行数:101,代码来源:JoinVerticesProcess.cpp

示例4: ASSIMP_LOG_INFO

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
{
    if (NULL != pMesh->mNormals)
        return false;

    // If the mesh consists of lines and/or points but not of
    // triangles or higher-order polygons the normal vectors
    // are undefined.
    if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
    {
        ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes");
        return false;
    }

    // Allocate the array to hold the output normals
    const float qnan = std::numeric_limits<ai_real>::quiet_NaN();
    pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];

    // Compute per-face normals but store them per-vertex
    for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
    {
        const aiFace& face = pMesh->mFaces[a];
        if (face.mNumIndices < 3)
        {
            // either a point or a line -> no normal vector
            for (unsigned int i = 0;i < face.mNumIndices;++i) {
                pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
            }

            continue;
        }

        const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
        const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
        const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
        const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();

        for (unsigned int i = 0;i < face.mNumIndices;++i) {
            pMesh->mNormals[face.mIndices[i]] = vNor;
        }
    }

    // Set up a SpatialSort to quickly find all vertices close to a given position
    // check whether we can reuse the SpatialSort of a previous step.
    SpatialSort* vertexFinder = NULL;
    SpatialSort  _vertexFinder;
    ai_real posEpsilon = ai_real( 1e-5 );
    if (shared) {
        std::vector<std::pair<SpatialSort,ai_real> >* avf;
        shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
        if (avf)
        {
            std::pair<SpatialSort,ai_real>& blubb = avf->operator [] (meshIndex);
            vertexFinder = &blubb.first;
            posEpsilon = blubb.second;
        }
    }
    if (!vertexFinder)  {
        _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
        vertexFinder = &_vertexFinder;
        posEpsilon = ComputePositionEpsilon(pMesh);
    }
    std::vector<unsigned int> verticesFound;
    aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];

    if (configMaxAngle >= AI_DEG_TO_RAD( 175.f ))   {
        // There is no angle limit. Thus all vertices with positions close
        // to each other will receive the same vertex normal. This allows us
        // to optimize the whole algorithm a little bit ...
        std::vector<bool> abHad(pMesh->mNumVertices,false);
        for (unsigned int i = 0; i < pMesh->mNumVertices;++i)   {
            if (abHad[i]) {
                continue;
            }

            // Get all vertices that share this one ...
            vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);

            aiVector3D pcNor;
            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
                const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
                if (is_not_qnan(v.x))pcNor += v;
            }
            pcNor.NormalizeSafe();

            // Write the smoothed normal back to all affected normals
            for (unsigned int a = 0; a < verticesFound.size(); ++a)
            {
                unsigned int vidx = verticesFound[a];
                pcNew[vidx] = pcNor;
                abHad[vidx] = true;
            }
        }
    }
    // Slower code path if a smooth angle is set. There are many ways to achieve
    // the effect, this one is the most straightforward one.
    else    {
        const ai_real fLimit = std::cos(configMaxAngle);
//.........这里部分代码省略.........
开发者ID:smalcom,项目名称:assimp,代码行数:101,代码来源:GenVertexNormalsProcess.cpp


注:本文中的SpatialSort类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。