GMC_DCL(int, NumSons) { tp_Sym Sym; if (num_ParseErrors > 0) return; /*select*/{ if (NumSons < 0) { /*select*/{ if (Typ < 0) { CollectSons(-NumSons); MakeNod(-Typ); EndLex(); }else{ Sym = TopOf_SymStack(); Pop_SymStack(); MakeLeaf(Typ, Sym); };}/*select*/; }else if (NumSons == 0) { /*select*/{ if (Typ < 0) { CollectSons(NumSons); MakeNod(-Typ); EndLex(); }else if (Typ == 0) { CollectSons(NumSons); }else{ MakeEmptyNod(Typ); };}/*select*/; }else{ if (NumSons > 1) CollectSons(NumSons); if (Typ != 0) MakeNod(Typ); };}/*select*/; }/*Action*/
void MakeLeaves() { // Make leaves kdbuffer_t *pkdb = (kdbuffer_t*)arg.leafbuffer.buffer; int size = BufferNumElements(&arg.leafbuffer); int i; kdbuffer_t kdb ALIGNED(16); // printf("thread %i leaves %i\n", arg.tid, size); for(i=0; i < size; i++) { memcpy_ls(&kdb, &pkdb[i], sizeof(kdbuffer_t)); MakeLeaf(&kdb); } // Copy remaining leaf pointers int leaf; if( (curleaf%4) == 0) leaf = curleaf - 4; else leaf = curleaf - (curleaf%4); memcpy_ea(&arg.pleaves[leaf], &leaves, sizeof(int[4])); }
// // Search the binary tree and add the given string // return true if it was added or false if it already // exists // HRESULT ConsoleArgs::TreeAdd(b_tree **root, LPCWSTR add) { // Special case - init the tree if it // doesn't already exist if (*root == NULL) { *root = MakeLeaf(add); return *root == NULL ? E_OUTOFMEMORY : S_OK; } size_t name_len = wcslen(add)+1; LPWSTR szCopy = (LPWSTR)VSAlloc(name_len * sizeof(WCHAR)); if (!szCopy) { m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL); return NULL; } HRESULT hr = StringCchCopyW (szCopy, name_len, add); ASSERT (SUCCEEDED (hr)); // otherwise, just let the template do the work hr = (*root)->Add(szCopy, _wcsicmp); if (hr != S_OK) // S_FALSE means it already existed VSFree(szCopy); return hr; }
void KDBuildJob::KDBuild(int maxleafsize, int extradepth, bool root) { kdbuffer_t l_kdb; kdbuffer_t r_kdb; int b = 0; if(BufferEmpty(kdbuffer[b])) { for(int i=0; i < njobs; i++) sem_post(&jobs[i]->sem); } // Make nodes while(! BufferEmpty(kdbuffer[b]) ) { kdbuffer_t *kdb = (kdbuffer_t*)kdbuffer[b]->buffer; int size = BufferNumElements(kdbuffer[b]); int i; BufferClear(aabb_buffer[1-b]); BufferClear(kdbuffer[1-b]); for(i=0; i < size; i++) { l_kdb.node = curnode++; r_kdb.node = curnode++; nodes[ kdb[i].node ].split = kdb[i].plane; nodes[ kdb[i].node ].axis = kdb[i].axis; nodes[ kdb[i].node ].left = l_kdb.node; nodes[ kdb[i].node ].right = r_kdb.node; KDBufferAllocate(&l_kdb, kdb[i].left_size, aabb_buffer[1-b]); if(curjob < njobs) KDBufferAllocate(&r_kdb, kdb[i].right_size, jobs[curjob]->aabb_buffer[0]); else KDBufferAllocate(&r_kdb, kdb[i].right_size, aabb_buffer[1-b]); KDPartition(&kdb[i], &l_kdb, &r_kdb); if(l_kdb.depth == maxdepth || l_kdb.size <= maxleafsize) { l_kdb.aabb = (aabb_t*)BufferCopyTo(leaf_aabb_buffer, l_kdb.aabb, l_kdb.count); BufferCopyTo(leafbuffer, &l_kdb, 1); } else BufferCopyTo(kdbuffer[1-b], &l_kdb, 1); if(r_kdb.depth == maxdepth || r_kdb.size <= maxleafsize) { if(curjob < njobs) { r_kdb.aabb = (aabb_t*)BufferCopyTo(jobs[curjob]->leaf_aabb_buffer, r_kdb.aabb, r_kdb.count); BufferCopyTo(jobs[curjob]->leafbuffer, &r_kdb, 1); } else { r_kdb.aabb = (aabb_t*)BufferCopyTo(leaf_aabb_buffer, r_kdb.aabb, r_kdb.count); BufferCopyTo(leafbuffer, &r_kdb, 1); } } else { if(curjob < njobs) BufferCopyTo(jobs[curjob]->kdbuffer[0], &r_kdb, 1); else BufferCopyTo(kdbuffer[1-b], &r_kdb, 1); } } if(curjob < njobs) { // Start other job sem_post(&jobs[curjob]->sem); curjob++; } b = 1 - b; } // Check if still remaining jobs and start them while(curjob < njobs) { // Start other job sem_post(&jobs[curjob]->sem); curjob++; } // Make leaves kdbuffer_t *kdb = (kdbuffer_t*)leafbuffer->buffer; int size = BufferNumElements(leafbuffer); //cout << "Make leaves " << size << endl; int i; for(i=0; i < size; i++) { MakeLeaf(&kdb[i]); } numleaves = size; curleaf = size; }
void BVHTree::BuildNode(BVHNode *node, const objPtr_t *objPtrs, const Aabb *objAabbs, std::vector<objPtr_t> &activeObjIdx) { const int numTris = activeObjIdx.size(); if (numTris <= 0) Error("BuildNode called with no elements in activeObjIndex."); if (numTris == 1) { MakeLeaf(node, objPtrs, activeObjIdx); return; } std::vector<int> splitSides(numTris); Aabb aabb; aabb.min = vector3d(FLT_MAX, FLT_MAX, FLT_MAX); aabb.max = vector3d(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (int i=0; i<numTris; i++) { int idx = activeObjIdx[i]; aabb.Update(objAabbs[idx].min); aabb.Update(objAabbs[idx].max); } node->numTris = numTris; node->aabb = aabb; Aabb splitBox = aabb; double splitPos; int splitAxis; int s1count, s2count; int attempt = 0; for (;;) { splitAxis = 0; vector3d boxSize = splitBox.max - splitBox.min; if (boxSize[1] > boxSize[0]) splitAxis = 1; if ((boxSize[2] > boxSize[1]) && (boxSize[2] > boxSize[0])) splitAxis = 2; // split pos in middle of splitBox splitPos = 0.5f * (splitBox.min[splitAxis] + splitBox.max[splitAxis]); s1count = 0, s2count = 0; for (int i=0; i<numTris; i++) { int idx = activeObjIdx[i]; double mid = 0.5 * (objAabbs[idx].min[splitAxis] + objAabbs[idx].max[splitAxis]); if (mid < splitPos) { splitSides[i] = 0; s1count++; } else { splitSides[i] = 1; s2count++; } } if (s1count == numTris) { if (attempt < MAX_SPLITPOS_RETRIES) { // try splitting at average point splitBox.max[splitAxis] = splitPos; attempt++; continue; } else { MakeLeaf(node, objPtrs, activeObjIdx); return; } } else if (s2count == numTris) { if (attempt < MAX_SPLITPOS_RETRIES) { // try splitting at average point splitBox.min[splitAxis] = splitPos; attempt++; continue; } else { MakeLeaf(node, objPtrs, activeObjIdx); return; } } break; } std::vector<int> side[2]; for (int i=0; i<numTris; i++) { side[splitSides[i]].push_back(activeObjIdx[i]); } // recurse! node->triIndicesStart = 0; node->kids[0] = AllocNode(); node->kids[1] = AllocNode(); BuildNode(node->kids[0], objPtrs, objAabbs, side[0]); BuildNode(node->kids[1], objPtrs, objAabbs, side[1]); }
void neTreeNode::Build(neSimpleArray<s32> & triIndex, s32 level) { neV3 maxBound, minBound, com; FindCenterOfMass(tree, triIndex, &com); s32 i; if (level > 10) { MakeLeaf(triIndex); return; } if (triIndex.GetUsedCount() < 4) { MakeLeaf(triIndex); return; } for (i = 0; i < 4; i++) { neSimpleArray<s32> sectorTris; CountTriangleInSector(triIndex, sectorTris, com, i); if (sectorTris.GetUsedCount()) { if (sectorTris.GetUsedCount() == triIndex.GetUsedCount()) { MakeLeaf(triIndex); return; } else { FindMinMaxBound(tree, sectorTris, minBound, maxBound); f32 yMin = minBound[1]; f32 yMax = maxBound[1]; neTreeNode * node = tree->nodes.Alloc(); ASSERT(node); SelectBound(com, minBound, maxBound, i); minBound[1] = yMin; maxBound[1] = yMax; if (this == &tree->root) node->Initialise(tree, -1, minBound, maxBound); else node->Initialise(tree, tree->nodes.GetIndex(this), minBound, maxBound); children[i] = tree->nodes.GetIndex(node); //ASSERT(children[i] != 159); tree->nodes[children[i]].Build(sectorTris, level + 1); } } else { children[i] = -1; } } }