Ejemplo n.º 1
0
bool Primitive::Intersect( Ray& ray, Intersection& isect )
{
	Ray localRay(ray);

	localRay.o = Vec3d(worldToLocal * Vec4d(ray.o, 1.0));
	localRay.d = Vec3d(worldToLocal * Vec4d(ray.d, 0.0));

	if (!shape->Intersect(localRay, isect))
	{
		return false;
	}

	ray.minT = localRay.minT;
	ray.maxT = localRay.maxT;

	if (localToWorld != Mat4d(1.0))
	{
		isect.p = Vec3d(localToWorld * Vec4d(isect.p, 1.0));
		isect.sn = Math::Normalize(normalLocalToWorld * isect.sn);
		isect.gn = Math::Normalize(normalLocalToWorld * isect.gn);
		isect.ss = Math::Normalize(Vec3d(localToWorld * Vec4d(isect.ss, 0.0)));
		isect.st = Math::Normalize(Vec3d(localToWorld * Vec4d(isect.st, 0.0)));
	}

	return true;
}
Ejemplo n.º 2
0
void CustomGeometry::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
    RayQueryLevel level = query.level_;
    
    switch (level)
    {
    case RAY_AABB_NOSUBOBJECTS:
    case RAY_AABB:
        Drawable::ProcessRayQuery(query, results);
        break;
        
    case RAY_OBB:
    case RAY_TRIANGLE:
        Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
        Ray localRay(inverse * query.ray_.origin_, inverse * Vector4(query.ray_.direction_, 0.0f));
        float distance = localRay.HitDistance(boundingBox_);
        if (distance <= query.maxDistance_)
        {
            if (level == RAY_TRIANGLE)
            {
                for (unsigned i = 0; i < batches_.Size(); ++i)
                {
                    Geometry* geometry = batches_[i].geometry_;
                    if (geometry)
                    {
                        distance = geometry->GetHitDistance(localRay);
                        if (distance <= query.maxDistance_)
                        {
                            RayQueryResult result;
                            result.drawable_ = this;
                            result.node_ = node_;
                            result.distance_ = distance;
                            result.subObject_ = M_MAX_UNSIGNED;
                            results.Push(result);
                            break;
                        }
                    }
                }
            }
            else
            {
                RayQueryResult result;
                result.drawable_ = this;
                result.node_ = node_;
                result.distance_ = distance;
                result.subObject_ = M_MAX_UNSIGNED;
                results.Push(result);
            }
        }
        break;
    }
}
Ejemplo n.º 3
0
void Light::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
    // Do not record a raycast result for a directional light, as it would block all other results
    if (lightType_ == LIGHT_DIRECTIONAL)
        return;

    float distance;
    switch (query.level_)
    {
    case RAY_AABB_NOSUBOBJECTS:
    case RAY_AABB:
        Drawable::ProcessRayQuery(query, results);
        return;

    case RAY_OBB:
        {
            Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
            Ray localRay(inverse * query.ray_.origin_, inverse * Vector4(query.ray_.direction_, 0.0f));
            distance = localRay.HitDistance(GetWorldBoundingBox().Transformed(inverse));
            if (distance >= query.maxDistance_)
                return;
        }
        break;

    case RAY_TRIANGLE:
        if (lightType_ == LIGHT_SPOT)
        {
            distance = query.ray_.HitDistance(GetFrustum());
            if (distance >= query.maxDistance_)
                return;
        }
        else // if (lightType_ == LIGHT_POINT)
        {
            distance = query.ray_.HitDistance(Sphere(node_->GetWorldPosition(), range_));
            if (distance >= query.maxDistance_)
                return;
        }
        break;
    }

    // If the code reaches here then we have a hit
    RayQueryResult result;
    result.drawable_ = this;
    result.node_ = node_;
    result.distance_ = distance;
    result.subObject_ = M_MAX_UNSIGNED;
    results.Push(result);
}
Ejemplo n.º 4
0
bool Geometry::intersect(const ray&r, isect&i) const
{
    // Transform the ray into the object's local coordinate space
    vec3f pos = transform->globalToLocalCoords(r.getPosition());
    vec3f dir = transform->globalToLocalCoords(r.getPosition() + r.getDirection()) - pos;
    double length = dir.length();
    dir /= length;

    ray localRay( pos, dir );

    if (intersectLocal(localRay, i)) {
        // Transform the intersection point & normal returned back into global space.
		i.N = transform->localToGlobalCoordsNormal(i.N);
		i.t /= length;
		return true;
    } else {
        return false;
    }
}
Ejemplo n.º 5
0
bool StaticModel::IsInsideLocal(const Vector3& point) const
{
    // Early-out if point is not inside bounding box
    if (boundingBox_.IsInside(point) == OUTSIDE)
        return false;

    Ray localRay(point, Vector3(1.0f, -1.0f, 1.0f));

    for (unsigned i = 0; i < batches_.Size(); ++i)
    {
        Geometry* geometry = batches_[i].geometry_;
        if (geometry)
        {
            if (geometry->IsInside(localRay))
                return true;
        }
    }

    return false;
}
Ejemplo n.º 6
0
	void generateRay(const Point2 &dirSample, const Point2 &lensSample, 
		Float timeSample, Ray &ray) const {
		++cameraRays;

		Float u = dirSample.x * m_invResolution.x,
			  v = dirSample.y * m_invResolution.y;

		Vector direction = squareToSphereY(u, v);
		Point2 uvPrime = sphereToSquareY(direction);

		if ((std::abs(uvPrime.x-u) > Epsilon || std::abs(uvPrime.y-v)>Epsilon) && u < 1 && v < 1 && u > 0 && v > 0)
			cout << uvPrime.toString() << " vs " << u << ", " << v << endl;

		/* Construct ray in camera space */
		Ray localRay(Point(0.0f), direction,
			m_shutterOpen + m_shutterOpenTime * timeSample);

		/* Transform into world space */
		m_cameraToWorld(localRay, ray);
	}
Ejemplo n.º 7
0
bool TriangleMesh::intersects(const Ray& ray, double& t) const
{
	if (!box.intersects(ray)) return false;

	Ray localRay(ray);
	bool any = false;
	double nearestT = ray.tmax;

	for (unsigned int i=0; i<m_nFaces; i++)
	{	
		bool intersects = faces[i]->intersects(localRay,nearestT);

		if (intersects)
		{
			t = nearestT;
			localRay.tmax = nearestT;
			any = true;
		}
	}
	return any;
}
Ejemplo n.º 8
0
bool Object::intersects(Ray const & ray, Intersection * intersection) {
  // We first move the ray to object space before computing the intersection
  Ray localRay(ray.from - this->position, ray.direction);

  if(this->hasRotation) {
    localRay.from = this->rotationMatrix * localRay.from;
    // No need to normalize because the rotation matrix already is
    localRay.direction = this->rotationMatrix * localRay.direction;
  }

  bool hasIntersection = computeIntersection(localRay, intersection);

  // Move back to world coordinates
  if(intersection != NULL) {
    if(this->hasRotation) {
      intersection->position = (this->rotationMatrixT * intersection->position);
      intersection->normal = (this->rotationMatrixT * intersection->normal);
    }
    intersection->position += this->position;
  }

  return hasIntersection;
}
Ejemplo n.º 9
0
bool TriangleMesh::checkIntersection(const Ray& ray, Vector& N, double& t) const
{
	if (!box.intersects(ray)) return false;

	Ray localRay(ray);
	bool any = false;
	double nearestT = ray.tmax;
	Vector normal;

	for (unsigned int i=0; i<m_nFaces; i++)
	{
		bool intersects = faces[i]->checkIntersection(localRay, normal, nearestT);

		if (intersects)
		{
			t = nearestT;
			localRay.tmax = nearestT;
			N = normal;
			any = true;
		}
	}
	return any;
}