Example #1
0
void Grid::initializeRayMarch(MarchingInfo &mi, const Ray &r, float tmin) const
{
    Vec3f rayOrigin = r.getOrigin();
    Vec3f rayDir = r.getDirection();

    Vec3f boxMin = mpBox->getMin();
    Vec3f boxMax = mpBox->getMax();

    float rayT;
    if (mpBox->Inside(rayOrigin))
        rayT = 0.0;
    else if (!mpBox->IntersectP(r, &rayT))
    {
        return;
    }
    
    printf("rayT=%f\n", rayT);
    Vec3f gridIntersect = r.pointAtParameter(rayT);
    cout << "gridIntersect=" << gridIntersect << endl;
    cout << "Box min=" << mpBox->getMin() << endl;
    printf("mVoxel:%d, %d, %d \n", mVoxel[0], mVoxel[1], mVoxel[2]);
    //MarchingInfo for indices
    int pos[3];
    int axis;
    int sign[3];
    float delta[3];
    float next[3];
    int indices[3];
    for (axis = 0; axis < 3; axis++) {
        pos[axis] = posToVoxel(gridIntersect, axis);
        if (rayDir[axis] != 0)
            sign[axis] = rayDir[axis] > 0 ? 1 : -1;

        if (sign[axis] >= 0) {
            next[axis] = rayT +
                (voxelToPos(pos[axis]+1, axis) - gridIntersect[axis])/rayDir[axis];
            delta[axis] = mVoxel[axis] / rayDir[axis];
        }
        else {
            next[axis] = rayT +
                (voxelToPos(pos[axis], axis) - gridIntersect[axis])/rayDir[axis];
            delta[axis] = mVoxel[axis] / rayDir[axis];
        }
    }
    printf("Indices:%d, %d, %d \n", pos[0], pos[1], pos[2]);
    mi.setIndices(pos[0], pos[1], pos[2]);
    mi.setSign(sign[0], sign[1], sign[2]);
    mi.setDelta(delta[0], delta[1], delta[2]);
    mi.setNext(next[0], next[1], next[2]);
    mi.set_tmin(rayT);
}
Example #2
0
// GridAccel Method Definitions
GridAccel::GridAccel(const vector<Reference<Primitive> > &p,
                     bool forRefined, bool refineImmediately)
    : gridForRefined(forRefined) {
    PBRT_GRID_STARTED_CONSTRUCTION(this, p.size());
    // Create reader-writeer mutex for grid
    rwMutex = RWMutex::Create();

    // Initialize _primitives_ with primitives for grid
    if (refineImmediately)
        for (u_int i = 0; i < p.size(); ++i)
            p[i]->FullyRefine(primitives);
    else
        primitives = p;

    // Compute bounds and choose grid resolution
    for (u_int i = 0; i < primitives.size(); ++i)
        bounds = Union(bounds, primitives[i]->WorldBound());
    Vector delta = bounds.pMax - bounds.pMin;

    // Find _voxelsPerUnitDist_ for grid
    int maxAxis = bounds.MaximumExtent();
    float invMaxWidth = 1.f / delta[maxAxis];
    Assert(invMaxWidth > 0.f);
    float cubeRoot = 3.f * powf(float(primitives.size()), 1.f/3.f);
    float voxelsPerUnitDist = cubeRoot * invMaxWidth;
    for (int axis = 0; axis < 3; ++axis) {
        NVoxels[axis] = Round2Int(delta[axis] * voxelsPerUnitDist);
        NVoxels[axis] = Clamp(NVoxels[axis], 1, 64);
    }
    PBRT_GRID_BOUNDS_AND_RESOLUTION(&bounds, NVoxels);

    // Compute voxel widths and allocate voxels
    for (int axis = 0; axis < 3; ++axis) {
        Width[axis] = delta[axis] / NVoxels[axis];
        InvWidth[axis] = (Width[axis] == 0.f) ? 0.f : 1.f / Width[axis];
    }
    int nVoxels = NVoxels[0] * NVoxels[1] * NVoxels[2];
    voxels = AllocAligned<Voxel *>(nVoxels);
    memset(voxels, 0, nVoxels * sizeof(Voxel *));

    // Add primitives to grid voxels
    for (u_int i = 0; i < primitives.size(); ++i) {
        // Find voxel extent of primitive
        BBox pb = primitives[i]->WorldBound();
        int vmin[3], vmax[3];
        for (int axis = 0; axis < 3; ++axis) {
            vmin[axis] = posToVoxel(pb.pMin, axis);
            vmax[axis] = posToVoxel(pb.pMax, axis);
        }

        // Add primitive to overlapping voxels
        PBRT_GRID_VOXELIZED_PRIMITIVE(vmin, vmax);
        for (int z = vmin[2]; z <= vmax[2]; ++z)
            for (int y = vmin[1]; y <= vmax[1]; ++y)
                for (int x = vmin[0]; x <= vmax[0]; ++x) {
                    int o = offset(x, y, z);
                    if (!voxels[o]) {
                        // Allocate new voxel and store primitive in it
                        voxels[o] = voxelArena.Alloc<Voxel>();
                        *voxels[o] = Voxel(primitives[i]);
                    }
                    else {
                        // Add primitive to already-allocated voxel
                        voxels[o]->AddPrimitive(primitives[i]);
                    }
                }
    }
    PBRT_GRID_FINISHED_CONSTRUCTION(this);
}
void Heightfield2::GetShadingGeometry(const Transform &obj2world, const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const {
    // Initialize _Triangle_ shading geometry with _n_ and _s_

    // *dgShading = dg;
    // return;

    Point p = Point(dg.u, dg.v, 0);
    int x = posToVoxel(p, 0);
    int y = posToVoxel(p, 1);
    int index1 = x + y*nx;
    int index2, index3;

    const Point &p1o = point[index1];
    if((dg.u-p1o.x)*width[1] > (dg.v-p1o.y)*width[0]){
        index2 = x+1 + y*nx;
        index3 = x+1 + (y+1)*nx;
    }else{
        index2 = x+1 + (y+1)*nx;
        index3 = x + (y+1)*nx;
    }
    const Point &p2o = point[index2];
    const Point &p3o = point[index3];
    const Normal &normal0 = normal[index1];
    const Normal &normal1 = normal[index2];
    const Normal &normal2 = normal[index3];

    // Compute barycentric coordinates for point
    float b[3];

    // Initialize _A_ and _C_ matrices for barycentrics
    float A[2][2] =
        { { p2o.x - p1o.x, p3o.x - p1o.x },
          { p2o.y - p1o.y, p3o.y - p1o.y } };
    float C[2] = { dg.u - p1o.x, dg.v - p1o.y };
    if (!SolveLinearSystem2x2(A, C, &b[1], &b[2])) {
        // Handle degenerate parametric mapping
        b[0] = b[1] = b[2] = 1.f/3.f;
    }
    else
        b[0] = 1.f - b[1] - b[2];

    // Use _n_ and _s_ to compute shading tangents for triangle, _ss_ and _ts_
    Normal ns;
    Vector ss, ts;
    ns = Normalize(obj2world(b[0] * normal0 + b[1] * normal1 + b[2] * normal2));
    ss = Normalize(dg.dpdu);
    
    ts = Cross(ss, ns);
    if (ts.LengthSquared() > 0.f) {
        ts = Normalize(ts);
        ss = Cross(ts, ns);
    }
    else
        CoordinateSystem((Vector)ns, &ss, &ts);
    Normal dndu, dndv;

    // Compute $\dndu$ and $\dndv$ for triangle shading geometry
    // Compute deltas for triangle partial derivatives of normal
    float du1 = p1o.x - p3o.x;
    float du2 = p2o.x - p3o.x;
    float dv1 = p1o.y - p3o.y;
    float dv2 = p2o.y - p3o.y;
    Normal dn1 = normal0 - normal2;
    Normal dn2 = normal1 - normal2;
    float determinant = du1 * dv2 - dv1 * du2;
    if (determinant == 0.f)
        dndu = dndv = Normal(0,0,0);
    else {
        float invdet = 1.f / determinant;
        dndu = ( dv2 * dn1 - dv1 * dn2) * invdet;
        dndv = (-du2 * dn1 + du1 * dn2) * invdet;
    }

    *dgShading = DifferentialGeometry(dg.p, ss, ts, obj2world(dndu), obj2world(dndv), dg.u, dg.v, dg.shape);
    dgShading->dudx = dg.dudx;  dgShading->dvdx = dg.dvdx;
    dgShading->dudy = dg.dudy;  dgShading->dvdy = dg.dvdy;
    dgShading->dpdx = dg.dpdx;  dgShading->dpdy = dg.dpdy;
}
Example #4
0
bool GridAccel::IntersectP(const Ray &ray) const {
    PBRT_GRID_INTERSECTIONP_TEST(const_cast<GridAccel *>(this), const_cast<Ray *>(&ray));
    RWMutexLock lock(*rwMutex, READ);
    // Check ray against overall grid bounds
    float rayT;
    if (bounds.Inside(ray(ray.mint)))
        rayT = ray.mint;
    else if (!bounds.IntersectP(ray, &rayT)) {
        PBRT_GRID_RAY_MISSED_BOUNDS();
        return false;
    }
    Point gridIntersect = ray(rayT);

    // Set up 3D DDA for ray
    float NextCrossingT[3], DeltaT[3];
    int Step[3], Out[3], Pos[3];
    for (int axis = 0; axis < 3; ++axis) {
        // Compute current voxel for axis
        Pos[axis] = posToVoxel(gridIntersect, axis);
        if (ray.d[axis] >= 0) {
            // Handle ray with positive direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis]+1, axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = Width[axis] / ray.d[axis];
            Step[axis] = 1;
            Out[axis] = NVoxels[axis];
        }
        else {
            // Handle ray with negative direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = -Width[axis] / ray.d[axis];
            Step[axis] = -1;
            Out[axis] = -1;
        }
    }

    // Walk grid for shadow ray
    for (;;) {
        int o = offset(Pos[0], Pos[1], Pos[2]);
        Voxel *voxel = voxels[o];
        PBRT_GRID_RAY_TRAVERSED_VOXEL(Pos, voxel ? voxel->size() : 0);
        if (voxel && voxel->IntersectP(ray, lock))
            return true;
        // Advance to next voxel

        // Find _stepAxis_ for stepping to next voxel
        int bits = ((NextCrossingT[0] < NextCrossingT[1]) << 2) +
                   ((NextCrossingT[0] < NextCrossingT[2]) << 1) +
                   ((NextCrossingT[1] < NextCrossingT[2]));
        const int cmpToAxis[8] = { 2, 1, 2, 1, 2, 2, 0, 0 };
        int stepAxis = cmpToAxis[bits];
        if (ray.maxt < NextCrossingT[stepAxis])
            break;
        Pos[stepAxis] += Step[stepAxis];
        if (Pos[stepAxis] == Out[stepAxis])
            break;
        NextCrossingT[stepAxis] += DeltaT[stepAxis];
    }
    return false;
}
bool Heightfield2::IntersectP(const Ray &r) const{
    Ray ray;
    (*WorldToObject)(r, &ray);

    float rayT;
    if(bounds.Inside(ray(ray.mint)))
        rayT = ray.mint;
    else if(!bounds.IntersectP(ray, &rayT))
        return false;
    Point gridIntersect = ray(rayT);
    
    // Set up 2D DDA for ray
    float NextCrossingT[2], DeltaT[2];
    int Step[2], Out[2], Pos[2];
    for (int axis = 0; axis < 2; ++axis) {
        // Compute current voxel for axis
        Pos[axis] = posToVoxel(gridIntersect, axis);
        if (ray.d[axis] >= 0) {
            // Handle ray with positive direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis]+1, axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = width[axis] / ray.d[axis];
            Step[axis] = 1;
            Out[axis] = nVoxels[axis];
        }
        else {
            // Handle ray with negative direction for voxel stepping
            NextCrossingT[axis] = rayT +
                (voxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.d[axis];
            DeltaT[axis] = -width[axis] / ray.d[axis];
            Step[axis] = -1;
            Out[axis] = -1;
        }
    }

    // Walk ray through voxel grid
    bool hitSomething = false;
    int index[3];
    for (;;) {

        // Check for intersection in current voxel and advance to next
        index[0] = Pos[0] + Pos[1]*nx;
        index[1] = Pos[0]+1 + Pos[1]*nx;
        index[2] = Pos[0]+1 + (Pos[1]+1)*nx;
        hitSomething |= TriangleIntersectP(r, index);
        if(hitSomething) return hitSomething;

        index[1] = Pos[0]+1 + (Pos[1]+1)*nx;
        index[2] = Pos[0] + (Pos[1]+1)*nx;
        hitSomething |= TriangleIntersectP(r, index);
        if(hitSomething) return hitSomething;

        // Advance to next voxel
        // Find _stepAxis_ for stepping to next voxel
        int stepAxis = (NextCrossingT[0] < NextCrossingT[1])? 0 : 1;
        Pos[stepAxis] += Step[stepAxis];
        if (Pos[stepAxis] == Out[stepAxis])
            break;
        NextCrossingT[stepAxis] += DeltaT[stepAxis];
    }
    return hitSomething;
}