Exemplo n.º 1
0
void IntegerTree::RecursiveBuild(unsigned int height, Node<Factorization>* n) {
  if (height > 0) {
    // Add composites and recurse
    vector<Candidate> candidates = table.GetCandidates();
    for(Candidate c : candidates) {
      Node<Factorization>* child = new Node<Factorization>(c.GetFactors());
      n->Add(child);
      if (height > 1) {
        table.PushComposite(c);
        RecursiveBuild(height - 1, child);
        table.PopComposite(c);
      }
    }

    // Add prime and recurse
    Node<Factorization>* child = new Node<Factorization>(
                                         Factorization(table.GetPrimeCount()));
    n->Add(child);
    if (height > 1) {
      table.PushPrime();
      RecursiveBuild(height - 1, child);
      table.PopPrime();
    }
  }
}
Exemplo n.º 2
0
 TreeNode *RecursiveBuild(vector<int> &preorder, vector<int> &inorder, int leftPre, int rightPre, int leftIn, int rightIn, unordered_map<int, int>&hash)
 {
     if (leftPre > rightPre)
         return NULL;
     int x = hash[preorder[leftPre]];
     TreeNode *root = new TreeNode(preorder[leftPre]);
     root->left = RecursiveBuild(preorder, inorder, leftPre+1, leftPre+x-leftIn, leftIn, x-1, hash);     // don't forget to minus leftIn
     root->right = RecursiveBuild(preorder, inorder, leftPre+x-leftIn+1, rightPre, x+1, rightIn, hash);
     return root;
 }
Exemplo n.º 3
0
BVH::BVH(ObjMesh& _mesh)
{
    mesh = _mesh;

    //build work list
    workList.reserve(mesh.faces.size());
    for(auto i = 0; i < mesh.faces.size(); ++i)
        workList.push_back(BVHPrimitiveInfo(i, BBox(mesh.vertices[mesh.faces[i].x], mesh.vertices[mesh.faces[i].y], mesh.vertices[mesh.faces[i].z])));

    //recursive build
    std::cout<<"Building BVH..."<<std::endl;
    orderedPrims.reserve(mesh.faces.size());
    root = RecursiveBuild(0, workList.size());
    std::cout<<"Totoal nodes: "<<totalNodes<<std::endl;
    std::cout<<"Max depth: "<<maxDepth<<std::endl;

    //replace mesh faces order with ordered one
    mesh.faces.swap(orderedPrims);

    //build linear bvh
    lbvh.reserve(totalNodes);
    for(auto i = 0; i < totalNodes; ++i)
        lbvh.push_back(LBVHNode());
    uint32_t offset = 0;
    Flatten(root, &offset);
    std::cout<<"Root max: ("<<lbvh[0].bMax.x<<", "<<lbvh[0].bMax.y<<", "<<lbvh[0].bMax.z<<")"<<std::endl;
    std::cout<<"Root min: ("<<lbvh[0].bMin.x<<", "<<lbvh[0].bMin.y<<", "<<lbvh[0].bMin.z<<")"<<std::endl;
}
Exemplo n.º 4
0
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int m = preorder.size();
        int n = inorder.size();
        assert(m==n);
        unordered_map<int, int> hash;
        for (int i = 0; i < n; i++)
            hash[inorder[i]] = i;

        return RecursiveBuild(preorder, inorder, 0, m-1, 0, n-1, hash);

    }
Exemplo n.º 5
0
void BVH::Build(vector<PrimitiveInfo>& build_data) {
    // Recursively build the BVH tree.
    size_t total_nodes = 0;
    LinkedNode* root = RecursiveBuild(build_data, 0, build_data.size(), &total_nodes);

    // Flatten the tree into a linear representation.
    _nodes.reserve(total_nodes);
    for (size_t i = 0; i < total_nodes; i++) {
        _nodes.emplace_back();
    }
    size_t offset = 0;
    FlattenTree(root, -1, &offset);
    assert(offset == total_nodes);

    // Release memory consumed by the linked tree.
    DeleteLinked(root);
}
Exemplo n.º 6
0
BVHNode* BVH::RecursiveBuild(uint32_t start, uint32_t end, uint32_t depth)
{
    maxDepth = fmaxf(depth, maxDepth);
    totalNodes++;
    BVHNode* node = new BVHNode;

    //compute bounds of all primitives in BVH node
    BBox bbox;
    for(auto i = start; i < end; ++i)
        bbox = Union(bbox, workList[i].bounds);

    uint32_t nPrims = end - start;
    //if number of primitives are less than threshold, create leaf node
    if(nPrims <= MAX_LEAF_PRIM_NUM)
    {
        uint32_t firstPrimOffset = orderedPrims.size();
        for(auto i = start; i < end; ++i)
        {
            auto pIdx = workList[i].pIdx;
            orderedPrims.push_back(mesh.faces[pIdx]);
        }
        node->InitLeaf(firstPrimOffset, nPrims, bbox);
    }
    else
    {
        //compute bound of primitive centroids, choose split dimension
        BBox centroidBounds;
        for(auto i = start; i < end; ++i)
            centroidBounds = Union(centroidBounds, workList[i].bounds.bcenter);

        // split along max span axis
        int dim = centroidBounds.MaxExtent();

        //partition primitives into two sets and build children
        uint32_t mid = (end + start) / 2;
        // if max span axis is too small, create a leaf node
        if((centroidBounds.bmax[dim] - centroidBounds.bmin[dim]) < 1e-4)
        {
            uint32_t firstPrimOffset = orderedPrims.size();
            for(auto i = start; i < end; ++i)
            {
                auto pIdx = workList[i].pIdx;
                orderedPrims.push_back(mesh.faces[pIdx]);
            }
            node->InitLeaf(firstPrimOffset, nPrims, bbox);

            return node;
        }

        //partition primitives based on SAH
        std::vector<BucketInfo> buckets(nBuckets);
        float extent = centroidBounds.bmax[dim] - centroidBounds.bmin[dim];
        for(auto i = start; i < end; ++i)
        {
            uint32_t b = nBuckets * ((workList[i].bounds.bcenter[dim] - centroidBounds.bmin[dim]) / extent);
            if(b == nBuckets) b -= 1;
            buckets[b].count++;
            buckets[b].bounds = Union(buckets[b].bounds, workList[i].bounds);
        }

        //compute costs for splitting after each bucket
        float cost[nBuckets - 1];
        for(auto i = 0; i < nBuckets - 1; ++i)
        {
            BBox b0, b1;
            int count0 = 0, count1 = 0;

            for(auto j = 0; j <= i; ++j)
            {
                b0 = Union(b0, buckets[j].bounds);
                count0 += buckets[j].count;
            }
            for(auto j = i + 1; j < nBuckets; ++j)
            {
                b1 = Union(b1, buckets[j].bounds);
                count1 += buckets[j].count;
            }

            cost[i] = (count0 * b0.SurfaceArea() + count1 * b1.SurfaceArea()) / bbox.SurfaceArea();
        }

        //find best split
        float minCost = cost[0];
        uint32_t bestSplit = 0;
        for(auto i = 1; i < nBuckets - 1; ++i)
        {
            if(cost[i] < minCost)
            {
                minCost = cost[i];
                bestSplit = i;
            }
        }

        //either create leaf or split at selected SAH bucket
        if(nPrims > MAX_LEAF_PRIM_NUM || minCost < nPrims)
        {
            auto compare = [&](BVHPrimitiveInfo& p) {
                auto b = nBuckets * ((p.bounds.bcenter[dim] - centroidBounds.bmin[dim]) / extent);
                b = (b == nBuckets) ? (b - 1) : b;
                return b <= bestSplit;
            };
            BVHPrimitiveInfo *pmid = std::partition(&workList[start], &workList[end - 1] + 1, compare);
            mid = pmid - &workList[0];
        }
        else
        {
            uint32_t firstPrimOffset = orderedPrims.size();
            for(auto i = start; i < end; ++i)
            {
                auto pIdx = workList[i].pIdx;
                orderedPrims.push_back(mesh.faces[pIdx]);
            }
            node->InitLeaf(firstPrimOffset, nPrims, bbox);

            return node;
        }

        node->InitInner(RecursiveBuild(start, mid, depth + 1), RecursiveBuild(mid, end, depth + 1));
    }

    return node;
}
Exemplo n.º 7
0
void mjAssimpModel::RecursiveBuild(aiNode* node, mjMatrixStack* matrixStack)
{
    float tempMatrix[16];
    float poseMatrix[16];


    aiMatrix4x4* baseTrans = &node->mTransformation;

    /*Matrix4::MultiplyMM(poseMatrix, 0,
                        (float* )baseTrans, 0,
                        modelMatrix, 0);*/

    matrixStack->Push((float*) baseTrans);

    for(unsigned i = 0; i < node->mNumMeshes; i++)
    {
        const aiMesh* assimpMesh = scene->mMeshes[node->mMeshes[i]]; // From the scene, fetch the mesh that is in use by the current node.
        if (meshes[node->mMeshes[i]] == NULL)
        {







            mjModelMesh* mjMesh = new mjModelMesh();

            meshes[node->mMeshes[i]] = mjMesh;

            mjMesh->drawOrderCount = 3*assimpMesh->mNumFaces;

            mjMesh->drawOrderBuffer = new unsigned short[mjMesh->drawOrderCount];

            mjMesh->vertexBuffer = new float[assimpMesh->mNumFaces*3*3]; // *3 because triangle, *3 because xyz

            mjMesh->normalBuffer = new float[assimpMesh->mNumFaces*3*3]; // *3 because triangle, *3 because xyz

            mjMesh->textureCoordsBuffer = new float[assimpMesh->mNumFaces*3*2]; // *3 because triangle, *3 because uv





            unsigned drawOrderIndex = 0;
            for (unsigned f = 0; f < assimpMesh->mNumFaces; f++)
            {
                aiFace* face =  &assimpMesh->mFaces[f];

                for (unsigned vIndex = 0; vIndex < assimpMesh->mNumVertices; vIndex++)
                {
                    mjMesh->vertexBuffer[0 + (vIndex*3)] = assimpMesh->mVertices[vIndex].x;
                    // Switchy switchy -y <-> z
                    mjMesh->vertexBuffer[1 + (vIndex*3)] = assimpMesh->mVertices[vIndex].z;
                    mjMesh->vertexBuffer[2 + (vIndex*3)] = -assimpMesh->mVertices[vIndex].y;


                    // Determine bounds of object
                    for (unsigned l = 0; l < 3; l++)
                    {

                        if (vertexBuffer[vIndex + l] < bounds[0 + l])
                        {
                            bounds[0 + l] = vertexBuffer[vIndex + l];
                        }

                        if (vertexBuffer[vIndex + l] > bounds[3 + l])
                        {
                            bounds[3 + l] = vertexBuffer[vIndex + l];
                        }
                    }


                    /*mjMesh->vertexBuffer[1 + (vIndex*3)] = assimpMesh->mVertices[vIndex].y;
                    mjMesh->vertexBuffer[2 + (vIndex*3)] = assimpMesh->mVertices[vIndex].z;*/


                    mjMesh->normalBuffer[0 + (vIndex*3)] = assimpMesh->mNormals[vIndex].x;
                    // Switchy switchy -y <-> z
                    mjMesh->normalBuffer[1 + (vIndex*3)] = assimpMesh->mNormals[vIndex].z;
                    mjMesh->normalBuffer[2 + (vIndex*3)] = -assimpMesh->mNormals[vIndex].y;

                    /*mjMesh->normalBuffer[1 + (vIndex*3)] = assimpMesh->mNormals[vIndex].y;
                    mjMesh->normalBuffer[2 + (vIndex*3)] = assimpMesh->mNormals[vIndex].z;*/

                    float texCoord = assimpMesh->mTextureCoords[0][vIndex].x;
                    mjMesh->textureCoordsBuffer[0 + (vIndex*2)] = texCoord;

                    texCoord = assimpMesh->mTextureCoords[0][vIndex].y;
                    mjMesh->textureCoordsBuffer[1 + (vIndex*2)] = 1-texCoord;
                }

                for (unsigned vIndex = 0; vIndex < face->mNumIndices; vIndex++)
                {
                    mjMesh->drawOrderBuffer[drawOrderIndex] = face->mIndices[vIndex];

                    /*unsigned vertexIndex = face->mIndices[vIndex];
                    mjMesh->vertexBuffer[0 + (drawOrderIndex*3)] = assimpMesh->mVertices[vertexIndex].x;
                    mjMesh->vertexBuffer[1 + (drawOrderIndex*3)] = assimpMesh->mVertices[vertexIndex].y;
                    mjMesh->vertexBuffer[2 + (drawOrderIndex*3)] = assimpMesh->mVertices[vertexIndex].z;

                    LOGI("drawOrder[%d]: %3.1f, %3.1f, %3.1f", mjMesh->vertexBuffer[0 + (drawOrderIndex*3)], mjMesh->vertexBuffer[1 + (drawOrderIndex*3)], mjMesh->vertexBuffer[2 + (drawOrderIndex*3)]);

                    mjMesh->normalBuffer[0 + (drawOrderIndex*3)] = assimpMesh->mNormals[vertexIndex].x;
                    mjMesh->normalBuffer[1 + (drawOrderIndex*3)] = assimpMesh->mNormals[vertexIndex].y;
                    mjMesh->normalBuffer[2 + (drawOrderIndex*3)] = assimpMesh->mNormals[vertexIndex].z;

                    float texCoord = assimpMesh->mTextureCoords[0][vertexIndex].x;
                    mjMesh->textureCoordsBuffer[0 + (drawOrderIndex*2)] = texCoord;

                    texCoord = assimpMesh->mTextureCoords[0][vertexIndex].y;
                    mjMesh->textureCoordsBuffer[1 + (drawOrderIndex*2)] = texCoord;*/



                    drawOrderIndex++;



                }
            }


            LOGI("Mesh %d has %d vertices   ", i, assimpMesh->mNumVertices);
        }
        //glDrawElements(GL_TRIANGLES, mesh->, GL_UNSIGNED_SHORT, mesh->mFaces->mIndices);
        checkGlError("afterDrawElements");
    }

    // honey I unrolled the children
    for (unsigned int n = 0; n < node->mNumChildren; n++)
    {
        RecursiveBuild(node->mChildren[n], matrixStack);
    }
    matrixStack->Pop();
}
Exemplo n.º 8
0
void mjAssimpModel::LoadFromFile(const char* fileName)
{
    mjMatrixStack* matrixStack = new mjMatrixStack();
    scene = aiImportFile(fileName,aiProcessPreset_TargetRealtime_MaxQuality);

    if (scene)
    {
        for (int i = 0; i < scene->mNumMaterials; i++)
        {
            // Keep trying to extract textures until it fails
            aiString textureFilename;

            aiMaterial* mat = scene->mMaterials[i];

            aiReturn textureFilenameWasExtracted;
            int diffuseTextureIndex = 0;

            do
            {
                textureFilenameWasExtracted = mat->GetTexture(aiTextureType_DIFFUSE, diffuseTextureIndex, &textureFilename);
                if (textureFilenameWasExtracted == AI_SUCCESS)
                {
                    // Load using the manager.

                    //FIXME: For now only the first texture is used :3

                    if (diffuseTextureIndex == 0)
                    {
                        std::string texFilenameWithoutJunk = textureFilename.C_Str();
                        int lastDirChar = texFilenameWithoutJunk.find_last_of('/');
                        int lastInvertDirChar = texFilenameWithoutJunk.find_last_of('\\');
                        if (lastInvertDirChar > lastDirChar)
                        {
                            lastDirChar = lastInvertDirChar;
                        }
                        texFilenameWithoutJunk = texFilenameWithoutJunk.substr(lastDirChar+1);
                        glTextureForMaterial.push_back(resManager->FetchTexture(texFilenameWithoutJunk, GL_REPEAT));
                    }
                }
                diffuseTextureIndex++;
            } while (textureFilenameWasExtracted == AI_SUCCESS);

        }


        // Now build the internal data structures ( structure, drawOrderBuffers, etc.)


        for (unsigned i = 0; i < scene->mNumMeshes; i++)
        {
            meshes.push_back(NULL);
        }



        aiNode* node = scene->mRootNode;


        RecursiveBuild(node, matrixStack);
    } else
    {
        LOGI("Assimp import error: %s", aiGetErrorString());
    }
    delete matrixStack;
}
Exemplo n.º 9
0
LinkedNode* BVH::RecursiveBuild(vector<PrimitiveInfo>& build_data, size_t start,
 size_t end, size_t* total_nodes) {
    assert(start != end);
    
    (*total_nodes)++;
    LinkedNode* node = nullptr;

    // Compute the bounds of all primitives in this BVH node.
    BoundingBox bounds;
    for (size_t i = start; i < end; i++) {
        bounds = bounds.Union(build_data[i].bounds);
    }

    // How many primitives are we partitioning?
    size_t num_primitives = end - start;
    if (num_primitives == 1) {
        // Only one primitive left, create a leaf node.
        node = new LinkedNode(build_data[start].index, bounds);
    } else {
        // Find the bounds of the centroids.
        BoundingBox centroid_bounds;
        for (size_t i = start; i < end; i++) {
            centroid_bounds.Absorb(build_data[i].centroid);
        }

        // Split along the longest axis.
        BoundingBox::Axis split_axis = centroid_bounds.LongestAxis();
        float split_min = AxisComponent(centroid_bounds.min, split_axis);
        float split_max = AxisComponent(centroid_bounds.max, split_axis);

        size_t mid = (start + end) / 2;
        if (num_primitives <= 4 || split_min == split_max) {
            // Partition using equal size subsets, since SAH has diminishing
            // returns at this point. Also handles a degenerate case where we
            // have multiple primitives stacked on top  of each other with the
            // same centroid.
            nth_element(&build_data[start], &build_data[mid], &build_data[end - 1] + 1,
             [split_axis](const PrimitiveInfo& a, const PrimitiveInfo& b) {
                 return AxisComponent(a.centroid, split_axis) < AxisComponent(b.centroid, split_axis);
             });
        } else {
            // Partition using the surface area heuristic (SAH).
            uint32_t min_cost_split = ComputeSAH(build_data, start, end,
             split_min, split_max, bounds.SurfaceArea(), split_axis);

            PrimitiveInfo* pmid = partition(&build_data[start],
             &build_data[end - 1] + 1, [min_cost_split, split_min, split_max, split_axis](const PrimitiveInfo& p) {
                 uint32_t bucket = NUM_BUCKETS *
                  ((AxisComponent(p.centroid, split_axis) - split_min) /
                  (split_max - split_min));

                 if (bucket == NUM_BUCKETS) bucket = NUM_BUCKETS - 1;
                 assert(bucket >= 0 && bucket < NUM_BUCKETS);

                 return bucket <= min_cost_split;
             });

            mid = pmid - &build_data[0];

        }

        // Recursively build the subtrees for both partitions.
        node = new LinkedNode(RecursiveBuild(build_data, start, mid, total_nodes),
                              RecursiveBuild(build_data, mid, end, total_nodes),
                              split_axis);
    }

    return node;
}