Ejemplo n.º 1
0
Bounds3f Curve::ObjectBound() const {
    // Compute object-space control points for curve segment, _cpObj_
    Point3f cpObj[4];
    cpObj[0] = BlossomBezier(common->cpObj, uMin, uMin, uMin);
    cpObj[1] = BlossomBezier(common->cpObj, uMin, uMin, uMax);
    cpObj[2] = BlossomBezier(common->cpObj, uMin, uMax, uMax);
    cpObj[3] = BlossomBezier(common->cpObj, uMax, uMax, uMax);
    Bounds3f b =
        Union(Bounds3f(cpObj[0], cpObj[1]), Bounds3f(cpObj[2], cpObj[3]));
    Float width[2] = {Lerp(uMin, common->width[0], common->width[1]),
                      Lerp(uMax, common->width[0], common->width[1])};
    return Expand(b, std::max(width[0], width[1]) * 0.5f);
}
Ejemplo n.º 2
0
void KdTreeAccel::update()
{
	int np = primitives.size();
	//Initialize bouding box for all primitives in stack
	treeBound = Bounds3f();
	for (int i = 0; i < np; ++i)
	{
		treeBound.Union(primitives[i]->ObjBound);
	}
	//Allocate bound edge info
	BoundEdge* edges[3];
	for (int i = 0; i < 3; ++i)
	{
		edges[i] = new BoundEdge[np * 2];
	}
	//Create stack to record primitive indices
	vector<int> primNum(np);
	for (int i = 0; i < np; ++i)
	{
		primNum[i] = i;
	}
	//Start recursively build the tree
	buildTree(root, treeBound, primNum, maxDepth, edges);

	//Clean data
	for (int i = 0; i < 3; ++i)
	{
		delete[] edges[i];
//		edges[i] = nullptr;
	}
}
Ejemplo n.º 3
0
Bounds3f Triangle::WorldBound() const {
    // Get triangle vertices in _p0_, _p1_, and _p2_
    const Point3f &p0 = mesh->p[v[0]];
    const Point3f &p1 = mesh->p[v[1]];
    const Point3f &p2 = mesh->p[v[2]];
    return Union(Bounds3f(p0, p1), p2);
}
Ejemplo n.º 4
0
Bounds3f Triangle::ObjectBound() const {
    // Get triangle vertices in _p0_, _p1_, and _p2_
    const Point3f &p0 = mesh->p[v[0]];
    const Point3f &p1 = mesh->p[v[1]];
    const Point3f &p2 = mesh->p[v[2]];
    return Union(Bounds3f((*WorldToObject)(p0), (*WorldToObject)(p1)),
                 (*WorldToObject)(p2));
}
Ejemplo n.º 5
0
// Cylinder Method Definitions
Bounds3f Cylinder::ObjectBound() const {
    return Bounds3f(Point3f(-radius, -radius, zMin),
                    Point3f(radius, radius, zMax));
}
Ejemplo n.º 6
0
bool Curve::recursiveIntersect(const Ray &ray, Float *tHit,
                               SurfaceInteraction *isect, const Point3f cp[4],
                               const Transform &rayToObject, Float u0, Float u1,
                               int depth) const {
    // Try to cull curve segment versus ray

    // Compute bounding box of curve segment, _curveBounds_
    Bounds3f curveBounds =
        Union(Bounds3f(cp[0], cp[1]), Bounds3f(cp[2], cp[3]));
    Float maxWidth = std::max(Lerp(u0, common->width[0], common->width[1]),
                              Lerp(u1, common->width[0], common->width[1]));
    curveBounds = Expand(curveBounds, 0.5 * maxWidth);

    // Compute bounding box of ray, _rayBounds_
    Float rayLength = ray.d.Length();
    Float zMax = rayLength * ray.tMax;
    Bounds3f rayBounds(Point3f(0, 0, 0), Point3f(0, 0, zMax));
    if (Overlaps(curveBounds, rayBounds) == false) return false;
    if (depth > 0) {
        // Split curve segment into sub-segments and test for intersection
        Float uMid = 0.5f * (u0 + u1);
        Point3f cpSplit[7];
        SubdivideBezier(cp, cpSplit);
        return (recursiveIntersect(ray, tHit, isect, &cpSplit[0], rayToObject,
                                   u0, uMid, depth - 1) ||
                recursiveIntersect(ray, tHit, isect, &cpSplit[3], rayToObject,
                                   uMid, u1, depth - 1));
    } else {
        // Intersect ray with curve segment

        // Test ray against segment endpoint boundaries
        Vector2f segmentDirection = Point2f(cp[3]) - Point2f(cp[0]);

        // Test sample point against tangent perpendicular at curve start
        Float edge =
            (cp[1].y - cp[0].y) * -cp[0].y + cp[0].x * (cp[0].x - cp[1].x);
        if (edge < 0) return false;

        // Test sample point against tangent perpendicular at curve end
        // TODO: update to match the starting test.
        Vector2f endTangent = Point2f(cp[2]) - Point2f(cp[3]);
        if (Dot(segmentDirection, endTangent) < 0) endTangent = -endTangent;
        if (Dot(endTangent, Vector2f(cp[3])) < 0) return false;

        // Compute line $w$ that gives minimum distance to sample point
        Float denom = Dot(segmentDirection, segmentDirection);
        if (denom == 0) return false;
        Float w = Dot(-Vector2f(cp[0]), segmentDirection) / denom;

        // Compute $u$ coordinate of curve intersection point and _hitWidth_
        Float u = Clamp(Lerp(w, u0, u1), u0, u1);
        Float hitWidth = Lerp(u, common->width[0], common->width[1]);
        Normal3f nHit;
        if (common->type == CurveType::Ribbon) {
            // Scale _hitWidth_ based on ribbon orientation
            Float sin0 = std::sin((1 - u) * common->normalAngle) *
                         common->invSinNormalAngle;
            Float sin1 =
                std::sin(u * common->normalAngle) * common->invSinNormalAngle;
            nHit = sin0 * common->n[0] + sin1 * common->n[1];
            hitWidth *= AbsDot(nHit, -ray.d / rayLength);
        }

        // Test intersection point against curve width
        Vector3f dpcdw;
        Point3f pc = EvalBezier(cp, Clamp(w, 0, 1), &dpcdw);
        Float ptCurveDist2 = pc.x * pc.x + pc.y * pc.y;
        if (ptCurveDist2 > hitWidth * hitWidth * .25) return false;
        if (pc.z < 0 || pc.z > zMax) return false;

        // Compute $v$ coordinate of curve intersection point
        Float ptCurveDist = std::sqrt(ptCurveDist2);
        Float edgeFunc = dpcdw.x * -pc.y + pc.x * dpcdw.y;
        Float v = (edgeFunc > 0.) ? 0.5f + ptCurveDist / hitWidth
                                  : 0.5f - ptCurveDist / hitWidth;

        // Compute hit _t_ and partial derivatives for curve intersection
        if (tHit != nullptr) {
            // FIXME: this tHit isn't quite right for ribbons...
            *tHit = pc.z / rayLength;
            // Compute error bounds for curve intersection
            Vector3f pError(2 * hitWidth, 2 * hitWidth, 2 * hitWidth);

            // Compute $\dpdu$ and $\dpdv$ for curve intersection
            Vector3f dpdu, dpdv;
            EvalBezier(common->cpObj, u, &dpdu);
            if (common->type == CurveType::Ribbon)
                dpdv = Normalize(Cross(nHit, dpdu)) * hitWidth;
            else {
                // Compute curve $\dpdv$ for flat and cylinder curves
                Vector3f dpduPlane = (Inverse(rayToObject))(dpdu);
                Vector3f dpdvPlane =
                    Normalize(Vector3f(-dpduPlane.y, dpduPlane.x, 0)) *
                    hitWidth;
                if (common->type == CurveType::Cylinder) {
                    // Rotate _dpdvPlane_ to give cylindrical appearance
                    Float theta = Lerp(v, -90., 90.);
                    Transform rot = Rotate(-theta, dpduPlane);
                    dpdvPlane = rot(dpdvPlane);
                }
                dpdv = rayToObject(dpdvPlane);
            }
            *isect = (*ObjectToWorld)(SurfaceInteraction(
                ray(pc.z), pError, Point2f(u, v), -ray.d, dpdu, dpdv,
                Normal3f(0, 0, 0), Normal3f(0, 0, 0), ray.time, this));
        }
        ++nHits;
        return true;
    }
}
Ejemplo n.º 7
0
Bounds3f Hyperboloid::ObjectBound() const {
    Point3f p1 = Point3f(-rMax, -rMax, zMin);
    Point3f p2 = Point3f(rMax, rMax, zMax);
    return Bounds3f(p1, p2);
}
Ejemplo n.º 8
0
Bounds3f OvrSceneView::GetBounds() const
{
	return ( WorldModel.Definition == NULL ) ?
			Bounds3f( Vector3f( 0, 0, 0 ), Vector3f( 0, 0, 0 ) ) :
			WorldModel.Definition->GetBounds();
}
Ejemplo n.º 9
0
// Disk Method Definitions
Bounds3f Disk::ObjectBound() const {
    return Bounds3f(Point3f(-radius, -radius, height),
                    Point3f(radius, radius, height));
}
Ejemplo n.º 10
0
Bounds3f BVHAccel::WorldBound() const {
    return nodes ? nodes[0].bounds : Bounds3f();
}
Ejemplo n.º 11
0
Bounds3f Paraboloid::ObjectBound() const {
    Point3f p1 = Point3f(-radius, -radius, zMin);
    Point3f p2 = Point3f(radius, radius, zMax);
    return Bounds3f(p1, p2);
}
Ejemplo n.º 12
0
//----------------------------------------------------------------------------------------------
void IDrawInterface::DoBuildWorldTransform_(const Matrix &WTM)
{
	m_WorldMatrixTransform = GetLTM_() * WTM * GetSTM_();

    m_Bounds.SetUnvalid(); // invalidate

    std::vector<IRenderInterface*> &vecRenderEntities = const_cast<CActor*>(m_pNode->m_pKey)->m_VecRenderEntities;
	for (std::vector<IRenderInterface*>::const_iterator iter = vecRenderEntities.begin(); iter != vecRenderEntities.end(); ++iter)
	{
		(*iter)->SetRWTM(m_WorldMatrixTransform);
	
		Bounds3f BBox = (*iter)->GetRBounds_();

		if (BBox.IsValid())
		{
            const unsigned int BBOX_POINTS = 8;

			Vector BoxPoints[BBOX_POINTS] =
			{ 
				/*Vector(BBox.bound_min.x, BBox.bound_min.y, BBox.bound_min.z),
				Vector(BBox.bound_min.x, BBox.bound_min.y, BBox.bound_max.z),
				Vector(BBox.bound_max.x, BBox.bound_min.y, BBox.bound_max.z),
				Vector(BBox.bound_max.x, BBox.bound_min.y, BBox.bound_min.z),

				Vector(BBox.bound_min.x, BBox.bound_max.y, BBox.bound_min.z),
				Vector(BBox.bound_min.x, BBox.bound_max.y, BBox.bound_max.z),
				Vector(BBox.bound_max.x, BBox.bound_max.y, BBox.bound_max.z),
				Vector(BBox.bound_max.x, BBox.bound_max.y, BBox.bound_min.z),*/

                // TODO make homogeneous with exporter tool
                Vector(BBox.bound_min.z, BBox.bound_min.y, BBox.bound_min.x),
                Vector(BBox.bound_max.z, BBox.bound_min.y, BBox.bound_min.x),
                Vector(BBox.bound_max.z, BBox.bound_min.y, BBox.bound_max.x),
                Vector(BBox.bound_min.z, BBox.bound_min.y, BBox.bound_max.x),

                Vector(BBox.bound_min.z, BBox.bound_max.y, BBox.bound_min.x),
                Vector(BBox.bound_max.z, BBox.bound_max.y, BBox.bound_min.x),
                Vector(BBox.bound_max.z, BBox.bound_max.y, BBox.bound_max.x),
                Vector(BBox.bound_min.z, BBox.bound_max.y, BBox.bound_max.x),
			}; 

			Matrix MT = m_WorldMatrixTransform;
			MT.t = Vector(0.f, 0.f, 0.f);

            Bounds3f tmpBound;
			for (int Index = 0; Index < BBOX_POINTS; ++Index)
			{
				Vector point = transform_coord(BoxPoints[Index], MT);
                
                if (Index == 0)
                {
                    tmpBound.SetBounds(point, point);
                    continue;
                }
                tmpBound.Add(point);
			}

            const Vector bound_min = m_WorldMatrixTransform.t + tmpBound.bound_min;
            const Vector bound_max = m_WorldMatrixTransform.t + tmpBound.bound_max;

            (*iter)->SetWBounds(Bounds3f(bound_min, bound_max));

            if (iter == vecRenderEntities.begin())
            {
                m_Bounds.SetBounds(bound_min, bound_max);
                continue;
            }
            else
            {
                m_Bounds.Add(bound_min);
                m_Bounds.Add(bound_max);
            }
		}
	}

    // invalidate composite bounds
    m_CompositeBounds = m_Bounds;
}
Ejemplo n.º 13
0
// Sphere Method Definitions
Bounds3f Sphere::ObjectBound() const {
    return Bounds3f(Point3f(-radius, -radius, zMin),
                    Point3f(radius, radius, zMax));
}