Origin *Locator::relocate(const Origin *origin) { _count++; // vvvvvvvvvvvvvvvvv // FIXME: This is still needed, but it would be better to get rid of it! // if the origin to relocate has a fixed depth, keep it fixed! if (fixedDepth(origin)) { setFixedDepth(origin->dep); } // ^^^^^^^^^^^^^^^^ /* else useFixedDepth(false); */ Origin* relo = _sc3relocate(origin); if (relo == NULL) return NULL; if (relo->dep <= _minDepth && relo->depthType != Origin::DepthManuallyFixed && ! usingFixedDepth()) { // relocate again, this time fixing the depth to _minDepth // NOTE: This reconfigures the locator temporarily! setFixedDepth(_minDepth, true); Origin *relo2 = _sc3relocate(origin); useFixedDepth(false); // restore free depth if (relo2 != NULL) { delete relo; relo = relo2; relo->depthType = Origin::DepthMinimum; } else { delete relo; return NULL; } } OriginQuality &q = relo->quality; if ( ! determineAzimuthalGaps(relo, &q.aziGapPrimary, &q.aziGapSecondary)) q.aziGapPrimary = q.aziGapSecondary = 360.; OriginErrorEllipsoid &e = relo->errorEllipsoid; e.sdobs = errorEllipsoid().sdobs; double norm = 1./e.sdobs; e.semiMajorAxis = norm*errorEllipsoid().smajax; e.semiMinorAxis = norm*errorEllipsoid().sminax; e.strike = norm*errorEllipsoid().strike; e.sdepth = norm*errorEllipsoid().sdepth; e.stime = norm*errorEllipsoid().stime; e.conf = errorEllipsoid().conf; return relo; }
//Returns true if the triangle is visible bool DepthBuffer::testTriangle2x2(const vec4f& v0,const vec4f& v1,const vec4f& v2){ VecS32 colOffset(0, 1, 0, 1); VecS32 rowOffset(0, 0, 1, 1); vec2i vertex[3]; vertex[0] = vec2i(int32(v0.x),int32(v0.y)); vertex[1] = vec2i(int32(v1.x),int32(v1.y)); vertex[2] = vec2i(int32(v2.x),int32(v2.y)); // Reject the triangle if any of its verts is behind the nearclip plane if(v0.w == 0.0f || v1.w == 0.0f || v2.w == 0.0f) return true; float minZ = std::min(v0.z,std::min(v1.z,v2.z)); VecF32 fixedDepth(minZ); // Fab(x, y) = Ax + By + C = 0 // Fab(x, y) = (ya - yb)x + (xb - xa)y + (xa * yb - xb * ya) = 0 // Compute A = (ya - yb) for the 3 line segments that make up each triangle auto A0 = vertex[1].y - vertex[2].y; auto A1 = vertex[2].y - vertex[0].y; auto A2 = vertex[0].y - vertex[1].y; // Compute B = (xb - xa) for the 3 line segments that make up each triangle auto B0 = vertex[2].x - vertex[1].x; auto B1 = vertex[0].x - vertex[2].x; auto B2 = vertex[1].x - vertex[0].x; // Compute C = (xa * yb - xb * ya) for the 3 line segments that make up each triangle auto C0 = vertex[1].x * vertex[2].y - vertex[2].x * vertex[1].y; auto C1 = vertex[2].x * vertex[0].y - vertex[0].x * vertex[2].y; auto C2 = vertex[0].x * vertex[1].y - vertex[1].x * vertex[0].y; // Use bounding box traversal strategy to determine which pixels to rasterize auto minx = std::max(std::min(std::min(vertex[0].x,vertex[1].x),vertex[2].x),0) & (~1); auto maxx = std::min(std::max(std::max(vertex[0].x,vertex[1].x),vertex[2].x),size_.x-2); auto miny = std::max(std::min(std::min(vertex[0].y,vertex[1].y),vertex[2].y),0) & (~1); auto maxy = std::min(std::max(std::max(vertex[0].y,vertex[1].y),vertex[2].y),size_.y-2); VecS32 a0(A0); VecS32 a1(A1); VecS32 a2(A2); VecS32 b0(B0); VecS32 b1(B1); VecS32 b2(B2); VecS32 col = VecS32(minx) + colOffset; VecS32 row = VecS32(miny) + rowOffset; auto rowIdx = miny*size_.x + 2 * minx; VecS32 w0_row = a0 * col + b0 * row + VecS32(C0); VecS32 w1_row = a1 * col + b1 * row + VecS32(C1); VecS32 w2_row = a2 * col + b2 * row + VecS32(C2); //Multiply each weight by two(rasterize 2x2 quad at once). a0 = shiftl<1>(a0); a1 = shiftl<1>(a1); a2 = shiftl<1>(a2); b0 = shiftl<1>(b0); b1 = shiftl<1>(b1); b2 = shiftl<1>(b2); for(int32 y = miny;y<=maxy;y+=2,rowIdx += 2 * size_.x){ auto w0 = w0_row; auto w1 = w1_row; auto w2 = w2_row; auto idx = rowIdx; for(int32 x = minx;x<=maxx;x+=2,idx+=4){ auto mask = w0|w1|w2; auto masks = _mm_movemask_ps(bits2float(mask).simd); if(masks != 0xF){ VecF32 previousDepth = VecF32::load(data_+idx); auto cmpMask = ((~masks)&0xF)& _mm_movemask_ps(cmple(fixedDepth,previousDepth).simd); if(cmpMask){ return true; } } w0+=a0; w1+=a1; w2+=a2; } w0_row += b0; w1_row += b1; w2_row += b2; } return false; }