Пример #1
0
float3 Ray::ClosestPoint(const Ray &other, float *d, float *d2) const
{
	float u, u2;
	float3 closestPoint = Line::ClosestPointLineLine(pos, pos + dir, other.pos, other.pos + other.dir, &u, &u2);
	if (u < 0.f && u2 < 0.f)
	{
		closestPoint = ClosestPoint(other.pos, &u);

		float3 closestPoint2 = other.ClosestPoint(pos, &u2);
		if (closestPoint.DistanceSq(other.pos) <= closestPoint2.DistanceSq(pos))
		{
			if (d)
				*d = u;
			if (d2)
				*d2 = 0.f;
			return closestPoint;
		}
		else
		{
			if (d)
				*d = 0.f;
			if (d2)
				*d2 = u2;
			return pos;
		}
	}
	else if (u < 0.f)
	{
		if (d)
			*d = 0.f;
		if (d2)
		{
			other.ClosestPoint(pos, &u2);
			*d2 = Max(0.f, u2);
		}
		return pos;
	}
	else if (u2 < 0.f)
	{
		float3 pt = ClosestPoint(other.pos, &u);
		u = Max(0.f, u);
		if (d)
			*d = u;
		if (d2)
			*d2 = 0.f;
		return pt;
	}
	else
	{
		if (d)
			*d = u;
		if (d2)
			*d2 = u2;
		return closestPoint;
	}
}
Пример #2
0
	void GizmoAxis::Update(Ray cameraRay, float scale, bool drag, const Vector3& camPos)
	{
		UI* ui = GetSubsystem<UI>();

		// Do not select when UI has modal element
		if (ui->HasModalElement())
		{
			selected = false;
			return;
		}

		Vector3 closest = cameraRay.ClosestPoint(axisRay);
		Vector3 projected = axisRay.Project(closest);
		d = axisRay.Distance(closest);
		t = (projected - axisRay.origin_).DotProduct(axisRay.direction_);

		// Determine the sign of d from a plane that goes through the camera position to the axis
		Plane axisPlane(camPos, axisRay.origin_, axisRay.origin_ + axisRay.direction_);
		if (axisPlane.Distance(closest) < 0.0)
			d = -d;

		// Update selected status only when not dragging
		if (!drag)
		{
			selected = (Abs(d) < axisMaxD * scale) && (t >= -axisMaxD * scale) && (t <= axisMaxT * scale);
			lastT = t;
			lastD = d;
		}
	}
Пример #3
0
Line Plane::NearEdge(Ray &ray)
{
    Line lines[] =
    {
        Line(v0, v1),
        Line(v1, v2),
        Line(v2, v3),
        Line(v3, v0)
    };

    int index = -1;

    float distance = 1e3f;

    for (int i = 0; i < 4; i++)
    {
        Ray rayEdge(lines[i].start, lines[i].end - lines[i].start);
        Vector3 closestPoint = ray.ClosestPoint(rayEdge);
        float dist = rayEdge.Distance(closestPoint);
        if (dist < distance)
        {
            distance = dist;
            index = i;
        }
    }

    return Line(lines[index].start, lines[index].end);
}
Пример #4
0
vec Ray::ClosestPoint(const Ray &other, float &d, float &d2) const
{
	Line::ClosestPointLineLine(pos, dir, other.pos, other.dir, d, d2);
	if (d < 0.f && d2 < 0.f)
	{
		vec closestPoint = ClosestPoint(other.pos, d);
		vec closestPoint2 = other.ClosestPoint(pos, d2);
		if (closestPoint.DistanceSq(other.pos) <= closestPoint2.DistanceSq(pos))
		{
			d2 = 0.f;
			return closestPoint;
		}
		else
		{
			d = 0.f;
			return pos;
		}
	}
	else if (d < 0.f)
	{
		d = 0.f;
		other.ClosestPoint(pos, d2);
		d2 = Max(0.f, d2);
		return pos;
	}
	else if (d2 < 0.f)
	{
		vec pt = ClosestPoint(other.pos, d);
		d = Max(0.f, d);
		d2 = 0.f;
		return pt;
	}
	else
	{
		return GetPoint(d);
	}
}