/* * calculateGradient */ void Volume::calculateGradient(void) { size_t depth = getDepth(); size_t height = getHeight(); size_t width = getWidth(); size_t szGrads = 4*width*height*depth; maximumGradient = FLT_MIN; minimumGradient = FLT_MAX; gradients = new float[szGrads]; for (size_t i = 0; i < szGrads; i++) gradients[i] = 0.0f; for (size_t k = 1; k < depth - 1; k++) { for (size_t j = 1; j < height - 1; j++) { for (size_t i = 1; i < width - 1; i++) { float x = float(getVoxel(i+1 + j * width + k * (width * height))) - float(getVoxel(i-1 + j * width + k * (width * height))); float y = float(getVoxel(i + (j+1) * width + k * (width * height))) - float(getVoxel(i + (j-1) * width + k * (width * height))); float z = float(getVoxel(i + j * width + (k+1) * (width * height))) - float(getVoxel(i + j * width + (k-1) * (width * height))); float m = x*x + y*y + z*z; gradients[4 * (i + j * width + k * (width * height)) + 0] = x; gradients[4 * (i + j * width + k * (width * height)) + 1] = y; gradients[4 * (i + j * width + k * (width * height)) + 2] = z; gradients[4 * (i + j * width + k * (width * height)) + 3] = m; if (maximumGradient < m) { maximumGradient = m; } if (minimumGradient > m) { minimumGradient = m; } } // end for } // end for } // end for } // end calculateGradient()
dvec4 VolumeVectorSampler::sample(const dvec4 &pos) const { dvec3 spatialPos = pos.xyz(); double t = pos.w; int tIndex = static_cast<int>(t); double tInterpolant = t - static_cast<float>(tIndex); dvec4 v0, v1; v0 = getVoxel(spatialPos, tIndex); v1 = getVoxel(spatialPos, tIndex + 1); return Interpolation<dvec4>::linear(v0, v1, tInterpolant); }
// TODO YukigassenChunkRoom should probably pass a pointer to an object that can store the triangles and filaments instead of passing pointer to itself. void YukigassenVoxelMap::setupInternalRenderingDataLocal(const YukigassenChunkRoom *ybr, YukigassenChunk *yukigassenChunk) { assert(ybr==getParentObj()); /*void YukigassenVoxelMap::setupInternalRenderingDataLocal(YukigassenChunk *yukigassenChunk) { const YukigassenChunkRoom *ybr=dynamic_cast<const YukigassenChunkRoom *>(getParentObj());*/ if (ybr!=NULL) { const float bsx2 = 0.5f * ybr->blockSizeX(); const float bsy2 = 0.5f * ybr->blockSizeY(); const float bsz2 = 0.5f * ybr->blockSizeZ(); const int subXo=ybr->translateToVoxelMapIndexX(geographicIndex)*mapSizeInBlocks.x; const int subYo=ybr->translateToVoxelMapIndexY(geographicIndex)*mapSizeInBlocks.y; const int subZo=ybr->translateToVoxelMapIndexZ(geographicIndex)*mapSizeInBlocks.z; //addLineBox(0.0f, 0.0f, 0.0f, rsx2, rsy2, rsz2); //printf("setupInternalRenderingDataLocal: %d %d %d\n", subXo, subYo, subZo); for(size_t lx=0;lx<mapSizeInBlocks.x;lx++) { for(size_t ly=0;ly<mapSizeInBlocks.y;ly++) { for(size_t lz=0;lz<mapSizeInBlocks.z;lz++) { const long long blockIndex = getBlockIndex(lx,ly,lz); const int b = getVoxel(blockIndex); if (!YukigassenChunk::getBlockInvisible(b)) { int rx=subXo+lx; int ry=subYo+ly; int rz=subZo+lz; // TODO Would be much faster to not do this via parent unless needed. int neighborMask = ybr->getNeighborMaskXp(rx,ry,rz) | ybr->getNeighborMaskYp(rx,ry,rz) | ybr->getNeighborMaskZp(rx,ry,rz) | ybr->getNeighborMaskXn(rx,ry,rz) | ybr->getNeighborMaskYn(rx,ry,rz) | ybr->getNeighborMaskZn(rx,ry,rz); //int neighborMask=0x1f; float xc = ybr->translateBlockToCoordinatesX(rx); float yc = ybr->translateBlockToCoordinatesY(ry); float zc = ybr->translateBlockToCoordinatesZ(rz); //printf("setupInternalRenderingDataLocal: %f %f %f %03x %d\n", xc, yc, zc, neighborMask, b); //if ((bsx2==bsy2) && (bsy2==bsz2)) {}; if (neighborMask!=0x3F) { yukigassenChunk->addTriangleBox(xc, yc, zc, bsx2, bsy2, bsz2, neighborMask, b); } } } } } } }
std::pair<s32, Voxel> BlockMap::getUpperVoxel(s32 x, s32 y, s32 minZ, s32 maxZ) { // TODO BlockMap: optimize getUpperVoxel() std::pair<s32,Voxel> p; Vector3i pos(x, y, maxZ); for(; pos.z >= minZ; pos.z--) { p.second = getVoxel(pos); if(p.second.type != voxel::AIR) break; } p.first = pos.z; return p; }
void CVolume3D::_computeSobelGradients(float *gradients, const int stride, int *sizes, const int dataType, const float gsliceDists[3]) { int idz, idy, idx; float *gp=gradients; const float weights[3][3][3][3] = { {{{-1, -3, -1}, {-3, -6, -3}, {-1, -3, -1}}, {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, {{ 1, 3, 1}, { 3, 6, 3}, { 1, 3, 1}}}, {{{-1, -3, -1}, { 0, 0, 0}, { 1, 3, 1}}, {{-3, -6, -3}, { 0, 0, 0}, { 3, 6, 3}}, {{-1, -3, -1}, { 0, 0, 0}, { 1, 3, 1}}}, {{{-1, 0, 1}, {-3, 0, 3}, {-1, 0, 1}}, {{-3, 0, 3}, {-6, 0, 6}, {-3, 0, 3}}, {{-1, 0, 1}, {-3, 0, 3}, {-1, 0, 1}}} }; fprintf(stderr, "computing gradients using SOBEL filter... may take a while\n"); for (idz = 0; idz < sizes[2]; idz++) { for (idy = 0; idy < sizes[1]; idy++) { for (idx = 0; idx < sizes[0]; idx++) { if ((idx > 0 && idx < sizes[0] - 1) && (idy > 0 && idy < sizes[1] - 1) && (idz > 0 && idz < sizes[2] - 1)) { sobelFilter3D(idx, idy, idz, weights, gsliceDists, gp); } else { /* X-direction */ if (idx < 1) { gp[0] = (getVoxel(idx + 1, idy, idz, dataType) - getVoxel(idx, idy, idz, dataType))* (gsliceDists[0]); } else { gp[0] = (getVoxel(idx, idy, idz, dataType) - getVoxel(idx - 1, idy, idz, dataType))* (gsliceDists[0]); } /* Y-direction */ if (idy < 1) { gp[1] = (getVoxel(idx, idy + 1, idz, dataType) - getVoxel(idx, idy, idz, dataType))* (gsliceDists[1]); } else { gp[1] = (getVoxel(idx, idy, idz, dataType) - getVoxel(idx, idy - 1, idz, dataType))* (gsliceDists[1]); } /* Z-direction */ if (idz < 1) { gp[2] = (getVoxel(idx, idy, idz + 1, dataType) - getVoxel(idx, idy, idz, dataType))* (gsliceDists[2]); } else { gp[2] = (getVoxel(idx, idy, idz, dataType) - getVoxel(idx, idy, idz - 1, dataType))* (gsliceDists[2]); } } gp += stride; } } } }
void scanUp(int xscan, int yscan, int zscan, float d, int ymax, int ymin) { float hx, hy; int by = 0; if(d < 0) { xscan += xdir; d += incy; hx = (float)xscan; if(xdir < 0) hx += 1.0f; hy = vy*(hx-posx)/vx + posy; by+=2; } else { yscan += ydir; d -= incx; hy = (float)yscan; if(ydir < 0) hy += 1.0f; hx = vx*(hy-posy)/vy + posx; } if(!inside(xscan, yscan, zscan)) { drawSegment(sx, ymin, ymax, 0); return; } float dist = cosang*(hx-posx) + sinang*(hy-posy); float f = xd/dist; int start = ymax; int startz = zscan; bool gap = false; for(int z=zscan; z>-0; --z) { int sy1 = (int)((z-posz+0)*f + yd); if(sy1 > ymax) continue; if(sy1 + f + f < ymin) break; uint8 voxel = getVoxel(xscan, yscan, z); if(voxel) { int sy2 = (int)((z-posz+1)*f + yd); if(sy2 > ymin) { sy1 = max(sy1, ymin); sy2 = min(sy2, ymax); if(sy2>sy1) drawSegment(sx, sy1, sy2, voxel+by ); } else sy2 = ymin; if(z+1>cz+2 || !getVoxel(xscan, yscan, z+1)) { float thx, thy; if(d < 0) { thx = (float)(xscan); if(xdir > 0) thx += 1.0f; thy = vy*(thx-posx)/vx + posy; } else { thy = (float)(yscan); if(ydir > 0) thy += 1.0f; thx = vx*(thy-posy)/vy + posx; } float dist2 = cosang*(thx-posx) + sinang*(thy-posy); float f2 = xd/dist2; int tsy = (int)((z-posz+1)*f2 + yd); if(tsy < ymin) break; tsy = min(tsy, ymax); if(tsy > sy2) { drawSegment(sx, sy2, tsy, voxel+5); sy2 = tsy; } } if(gap) { if(sy2 < start) scanUp(xscan, yscan, startz, d, start, sy2); gap = false; } start = sy1; startz = z-1; } else { gap = true; } } if(ymin < start) scanUp(xscan, yscan, startz, d, start, ymin); }