/*! SLButton::setPositionRecursive set the button position recursive */ void SLButton::setPosRec(SLfloat x, SLfloat y) { _minX = x; _minY = y; if (_children.size()>0) { // set children Y-pos. according to its parent SLfloat curChildY = _minY; SLfloat childH = ((SLButton*)_children[0])->btnH(); if (_children.size()>2) curChildY -= (_children.size()/2) * (childH + _sv->dpmm()*BTN_GAP_H_MM); curChildY = SL_max(curChildY, minMenuPos.y); // Loop through children & set their position for (auto child : _children) { SLButton* btn = (SLButton*)child; btn->setPosRec(_minX + _btnW + _sv->dpmm()*BTN_GAP_W_MM, curChildY); curChildY += btn->btnH() + _sv->dpmm()*BTN_GAP_H_MM; } } }
/*! Builds the uniform grid for ray tracing acceleration */ void SLUniformGrid::build(SLVec3f minV, SLVec3f maxV) { _minV = minV; _maxV = maxV; deleteAll(); // Calculate uniform grid // Calc. voxel resolution, extent and allocate voxel array SLVec3f size = _maxV - _minV; // Woo's method SLfloat voxDensity = 20.0f; SLuint numT = _m->numI / 3; // NO. of triangles SLfloat nr = (SLfloat)pow(voxDensity*numT,1.0f/3.0f); SLfloat maxS = SL_max(size.x, size.y, size.z); _voxResX = max(1, (SLint)(nr*size.x/maxS)); _voxResY = max(1, (SLint)(nr*size.y/maxS)); _voxResZ = max(1, (SLint)(nr*size.z/maxS)); _voxResXY= _voxResX * _voxResY; _voxCnt = _voxResZ * _voxResXY; _voxExtX = size.x / _voxResX; _voxExtY = size.y / _voxResY; _voxExtZ = size.z / _voxResZ; // Allocate array of pointer to SLV32ushort _vox = new SLV32ushort*[_voxCnt]; for (SLuint i=0; i<_voxCnt; ++i) _vox[i] = 0; SLint x, y, z; SLuint i, curVoxel = 0; SLfloat boxHalfExt[3] = {_voxExtX*0.5f, _voxExtY*0.5f, _voxExtZ*0.5f}; SLfloat curVoxelCenter[3]; SLfloat vert[3][3]; SLuint voxCntNotEmpty = 0; // Loop through all triangles and assign them to the voxels for(SLuint t = 0; t < numT; ++t) { // Copy triangle vertices into SLfloat array[3][3] SLuint i = t * 3; if (_m->I16) { vert[0][0] = _m->finalP()[_m->I16[i ]].x; vert[0][1] = _m->finalP()[_m->I16[i ]].y; vert[0][2] = _m->finalP()[_m->I16[i ]].z; vert[1][0] = _m->finalP()[_m->I16[i+1]].x; vert[1][1] = _m->finalP()[_m->I16[i+1]].y; vert[1][2] = _m->finalP()[_m->I16[i+1]].z; vert[2][0] = _m->finalP()[_m->I16[i+2]].x; vert[2][1] = _m->finalP()[_m->I16[i+2]].y; vert[2][2] = _m->finalP()[_m->I16[i+2]].z; } else { vert[0][0] = _m->finalP()[_m->I32[i ]].x; vert[0][1] = _m->finalP()[_m->I32[i ]].y; vert[0][2] = _m->finalP()[_m->I32[i ]].z; vert[1][0] = _m->finalP()[_m->I32[i+1]].x; vert[1][1] = _m->finalP()[_m->I32[i+1]].y; vert[1][2] = _m->finalP()[_m->I32[i+1]].z; vert[2][0] = _m->finalP()[_m->I32[i+2]].x; vert[2][1] = _m->finalP()[_m->I32[i+2]].y; vert[2][2] = _m->finalP()[_m->I32[i+2]].z; } // Min. and max. point of triangle SLVec3f minT = SLVec3f(SL_min(vert[0][0], vert[1][0], vert[2][0]), SL_min(vert[0][1], vert[1][1], vert[2][1]), SL_min(vert[0][2], vert[1][2], vert[2][2])); SLVec3f maxT = SLVec3f(SL_max(vert[0][0], vert[1][0], vert[2][0]), SL_max(vert[0][1], vert[1][1], vert[2][1]), SL_max(vert[0][2], vert[1][2], vert[2][2])); // min voxel index of triangle SLint minx = (SLint)((minT.x-_minV.x) / _voxExtX); SLint miny = (SLint)((minT.y-_minV.y) / _voxExtY); SLint minz = (SLint)((minT.z-_minV.z) / _voxExtZ); // max voxel index of triangle SLint maxx = (SLint)((maxT.x-_minV.x) / _voxExtX); SLint maxy = (SLint)((maxT.y-_minV.y) / _voxExtY); SLint maxz = (SLint)((maxT.z-_minV.z) / _voxExtZ); if (maxx >= _voxResX) maxx=_voxResX-1; if (maxy >= _voxResY) maxy=_voxResY-1; if (maxz >= _voxResZ) maxz=_voxResZ-1; // Loop through voxels curVoxelCenter[2] = _minV.z + minz*_voxExtZ + boxHalfExt[2]; for (z=minz; z<=maxz; ++z, curVoxelCenter[2] += _voxExtZ) { curVoxelCenter[1] = _minV.y + miny*_voxExtY + boxHalfExt[1]; for (y=miny; y<=maxy; ++y, curVoxelCenter[1] += _voxExtY) { curVoxelCenter[0] = _minV.x + minx*_voxExtX + boxHalfExt[0]; for (x=minx; x<=maxx; ++x, curVoxelCenter[0] += _voxExtX) { curVoxel = x + y*_voxResX + z*_voxResXY; //triangle-AABB overlap test by Thomas Möller if (triBoxOverlap(curVoxelCenter, boxHalfExt, vert)) //trianlgesAABB-AABB overlap test is faster but not as precise //if (triBoxBoxOverlap(curVoxelCenter, boxHalfExt, vert)) { { if (_vox[curVoxel] == 0) { voxCntNotEmpty++; _vox[curVoxel] = new SLV32ushort; } _vox[curVoxel]->push_back(t); if (_vox[curVoxel]->size() > _voxMaxTria) _voxMaxTria = _vox[curVoxel]->size(); } } } } } } _voxCntEmpty = _voxCnt - voxCntNotEmpty; // Reduce dynamic arrays to real size for (i=0; i<_voxCnt; ++i) { if (_vox[i]) _vox[i]->reserve(_vox[i]->size()); } /* // dump for debugging SL_LOG("\nMesh name: %s\n", _m->name().c_str()); SL_LOG("Number of voxels: %d\n", _voxCnt); SL_LOG("Empty voxels: %4.0f%%\n", (SLfloat)(_voxCnt-voxCntNotEmpty)/(SLfloat)_voxCnt * 100.0f); SL_LOG("Avg. tria. per voxel: %4.1f\n", (SLfloat)_m->numF/(SLfloat)voxCntNotEmpty); // dump voxels curVoxel = 0; curVoxelCenter[2] = _minV.z + boxHalfExt[2]; for (z=0; z<_voxResZ; ++z, curVoxelCenter[2] += _voxExtZ) { curVoxelCenter[1] = _minV.y + boxHalfExt[1]; for (y=0; y<_voxResY; ++y, curVoxelCenter[1] += _voxExtY) { curVoxelCenter[0] = _minV.x + boxHalfExt[0]; for (x=0; x<_voxResX; ++x, curVoxelCenter[0] += _voxExtX) { SL_LOG("\t%0d(%3.1f,%3.1f,%3.1f):%0d " ,curVoxel, curVoxelCenter[0], curVoxelCenter[1], curVoxelCenter[2], _vox[curVoxel].size()); curVoxel++; } SL_LOG("\n"); } SL_LOG("\n"); } */ }