Example #1
0
const vector4 vector4::operator / (const vector4 &v2) const
{
	vector4 r;
	r.x() = x() / v2.x();
	r.y() = y() / v2.y();
	r.z() = z() / v2.z();
	r.w() = w() / v2.w();
	return r;
}
Example #2
0
vector4 vector4::Transform(const vector4& v, const matrix& m)
{
	vector4 result = vector4( 
						(v.x() * m(0,0)) + (v.y() * m(1,0)) + (v.z() * m(2,0)) + (v.w() * m(3,0)),
						(v.x() * m(0,1)) + (v.y() * m(1,1)) + (v.z() * m(2,1)) + (v.w() * m(3,1)),
						(v.x() * m(0,2)) + (v.y() * m(1,2)) + (v.z() * m(2,2)) + (v.w() * m(3,2)),
						(v.x() * m(0,3)) + (v.y() * m(1,3)) + (v.z() * m(2,3)) + (v.w() * m(3,3)) );
	return result;
	
}
Example #3
0
// Returns the cross product of two vectors
vector4 vector4::Cross(const vector4 &v2) const
{
	vector4 r;
	r.x() = (y() * v2.z()) - (z() * v2.y());
	r.y() = (z() * v2.x()) - (x() * v2.z());
	r.z() = (x() * v2.y()) - (y() * v2.x());
	r.w() = w();	
	return r;
}
Example #4
0
float vector4::Dot(const vector4& v1, const vector4& v2)
{
	return v1.Dot(v2);
}
Example #5
0
// Returns the dot product of two vectors
float vector4::Dot(const vector4 &v2) const
{
	return ((x() * v2.x()) + (y() * v2.y()) + (z() * v2.z()) + (w() * v2.w()));
}
Example #6
0
// Equality operations
bool vector4::operator == (const vector4 &v) const
{
	return ((x() == v.x()) && (y() == v.y()) && (z() == v.z()) && (w() == v.w()));
}
Example #7
0
	bool RayIntersectsAABB(const ray& intersectionRay, float* tEntry, float* tExit, const vector4& aabbMinExtents, const vector4& aabbMaxExtents)
	{
		// Test against front plane.
		const vector4& rayPosition = intersectionRay.getPosition();
		const vector4& rayDirection = intersectionRay.getDirection();

		bool tFound = false;
		float minimumTValue = FLT_MAX;
		float maximumTValue = 0.0f;

		// Containment test. Is the ray inside the aabb?
		if (rayPosition.extractX() >= aabbMinExtents.extractX() &&
			rayPosition.extractX() <= aabbMaxExtents.extractX() &&
			rayPosition.extractY() >= aabbMinExtents.extractY() &&
			rayPosition.extractY() <= aabbMaxExtents.extractY() &&
			rayPosition.extractZ() >= aabbMinExtents.extractZ() &&
			rayPosition.extractZ() <= aabbMaxExtents.extractZ())
		{
			minimumTValue = 0.0f;

			tFound = true;
		}

		// Intersect ray with the minimum x plane of the aabb.
		plane minXPlane(vector4(aabbMinExtents.extractX(), 0.0f, 0.0f, 1.0f), vector4(-1.0f, 0.0f, 0.0f, 0.0f));

		float minXPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, minXPlane, &minXPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, minXPlaneIntersection, point);

			if (point.extractY() >= aabbMinExtents.extractY() &&
				point.extractY() <= aabbMaxExtents.extractY() &&
				point.extractZ() >= aabbMinExtents.extractZ() &&
				point.extractZ() <= aabbMaxExtents.extractZ())
			{
				if (minXPlaneIntersection >= 0.0f)
					tFound = true;

				if (minXPlaneIntersection < minimumTValue)
					minimumTValue = minXPlaneIntersection;

				if (minXPlaneIntersection > maximumTValue)
					maximumTValue = minXPlaneIntersection;
			}
		}

		// Intersect ray with the maximum x plane of the aabb.
		plane maxXPlane(vector4(aabbMaxExtents.extractX(), 0.0f, 0.0f, 1.0f), vector4(1.0f, 0.0f, 0.0f, 0.0f));

		float maxXPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, maxXPlane, &maxXPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, maxXPlaneIntersection, point);

			if (point.extractY() >= aabbMinExtents.extractY() &&
				point.extractY() <= aabbMaxExtents.extractY() &&
				point.extractZ() >= aabbMinExtents.extractZ() &&
				point.extractZ() <= aabbMaxExtents.extractZ())
			{
				if (maxXPlaneIntersection >= 0.0f)
					tFound = true;

				if (maxXPlaneIntersection < minimumTValue)
					minimumTValue = maxXPlaneIntersection;

				if (maxXPlaneIntersection > maximumTValue)
					maximumTValue = maxXPlaneIntersection;
			}
		}

		// Intersect ray with the minimum y plane of the aabb.
		plane minYPlane(vector4(0.0f, aabbMinExtents.extractY(), 0.0f, 1.0f), vector4(0.0f, -1.0f, 0.0f, 0.0f));

		float minYPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, minYPlane, &minYPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, minYPlaneIntersection, point);

			if (point.extractX() >= aabbMinExtents.extractX() &&
				point.extractX() <= aabbMaxExtents.extractX() &&
				point.extractZ() >= aabbMinExtents.extractZ() &&
				point.extractZ() <= aabbMaxExtents.extractZ())
			{
				if (minYPlaneIntersection >= 0.0f)
					tFound = true;

				if (minYPlaneIntersection < minimumTValue)
					minimumTValue = minYPlaneIntersection;

				if (minYPlaneIntersection > maximumTValue)
					maximumTValue = minYPlaneIntersection;
			}
		}

		// Intersect ray with the maximum y plane of the aabb.
		plane maxYPlane(vector4(0.0f, aabbMaxExtents.extractY(), 0.0f, 1.0f), vector4(0.0f, 1.0f, 0.0f, 0.0f));

		float maxYPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, maxYPlane, &maxYPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, maxYPlaneIntersection, point);

			if (point.extractX() >= aabbMinExtents.extractX() &&
				point.extractX() <= aabbMaxExtents.extractX() &&
				point.extractZ() >= aabbMinExtents.extractZ() &&
				point.extractZ() <= aabbMaxExtents.extractZ())
			{
				if (maxYPlaneIntersection >= 0.0f)
					tFound = true;

				if (maxYPlaneIntersection < minimumTValue)
					minimumTValue = maxYPlaneIntersection;

				if (maxYPlaneIntersection > maximumTValue)
					maximumTValue = maxYPlaneIntersection;
			}
		}

		// Intersect ray with the minimum z plane of the aabb.
		plane minZPlane(vector4(0.0f, 0.0f, aabbMinExtents.extractZ(), 1.0f), vector4(0.0f, 0.0f, -1.0f, 0.0f));

		float minZPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, minZPlane, &minZPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, minZPlaneIntersection, point);

			if (point.extractX() >= aabbMinExtents.extractX() &&
				point.extractX() <= aabbMaxExtents.extractX() &&
				point.extractY() >= aabbMinExtents.extractY() &&
				point.extractY() <= aabbMaxExtents.extractY())
			{
				if (minZPlaneIntersection >= 0.0f)
					tFound = true;

				if (minZPlaneIntersection < minimumTValue)
					minimumTValue = minZPlaneIntersection;

				if (minZPlaneIntersection > maximumTValue)
					maximumTValue = minZPlaneIntersection;
			}
		}

		// Intersect ray with the maximum z plane of the aabb.
		plane maxZPlane(vector4(0.0f, 0.0f, aabbMaxExtents.extractZ(), 1.0f), vector4(0.0f, 0.0f, 1.0f, 0.0f));

		float maxZPlaneIntersection;
		if (MathLib::intersectRayWithPlane(intersectionRay, maxZPlane, &maxZPlaneIntersection))
		{
			// Construct the point on the plane. Test if in bounds of the aabb.
			vector4 point;
			vector4_addScaledVector(rayPosition, rayDirection, maxZPlaneIntersection, point);

			if (point.extractX() >= aabbMinExtents.extractX() &&
				point.extractX() <= aabbMaxExtents.extractX() &&
				point.extractY() >= aabbMinExtents.extractY() &&
				point.extractY() <= aabbMaxExtents.extractY())
			{
				if (maxZPlaneIntersection >= 0.0f)
					tFound = true;

				if (maxZPlaneIntersection < minimumTValue)
					minimumTValue = maxZPlaneIntersection;

				if (maxZPlaneIntersection > maximumTValue)
					maximumTValue = maxZPlaneIntersection;
			}
		}

		if (tFound)
		{
			*tEntry = minimumTValue;
			*tExit = maximumTValue;
		}

		return tFound;
	}
Example #8
0
fcppt::unique_ptr<fruitapp::fruit::cut_mesh_result>
fruitapp::fruit::cut_mesh(
	fruit::mesh const &input_mesh,
	fruit::plane const &input_plane)
{
	typedef
	sge::renderer::scalar
	scalar;

	typedef
	sge::renderer::vector2
	vector2;

	typedef
	sge::renderer::vector3
	vector3;

	typedef
	fruitlib::def_ctor<
		vector2
	>
	geometry_vector2;

	typedef
	sge::renderer::vector4
	vector4;

	typedef
	sge::renderer::matrix4
	matrix4;

	typedef
	fcppt::math::box::object<scalar,2>
	box2;

	typedef
	fruitlib::def_ctor<
		box2
	>
	geometry_box2;

	typedef
	fcppt::math::box::object<scalar,3>
	box3;

	fcppt::unique_ptr<fruit::cut_mesh_result> result{
		fcppt::make_unique_ptr<fruit::cut_mesh_result>()};

	scalar const epsilon =
		static_cast<scalar>(
			0.01);

	typedef
	std::vector<vector3>
	vector3_sequence;

	vector3_sequence border;

	// First step: Collect all the triangles and the border points.
	for(
		mesh::triangle_sequence::const_iterator input_triangle =
			input_mesh.triangles().begin();
		input_triangle != input_mesh.triangles().end();
		++input_triangle)
	{
		typedef
		fruitlib::math::triangle_plane_intersection<triangle>
		intersection;

		scalar const inner_epsilon =
			static_cast<scalar>(
				0.00001);

		intersection const single_result =
			fruitlib::math::cut_triangle_at_plane(
				*input_triangle,
				input_plane,
				inner_epsilon);

		for(
			intersection::point_sequence::const_iterator current_is_point =
				single_result.points().begin();
			current_is_point != single_result.points().end();
			++current_is_point)
			border.push_back(
				*current_is_point);
		// Only add new points if they're not already in the set
		/*
		BOOST_FOREACH(
			intersection::point_sequence::const_reference r,
			single_result.points())
			if(
				boost::range::find_if(
					border,
					boost::phoenix::bind(
						&fcppt::math::range_compare
						<
							sge::renderer::vector3,
							sge::renderer::vector3,
							sge::renderer::scalar
						>,
						boost::phoenix::arg_names::arg1,
						r,
						epsilon)) == border.end())
				border.push_back(
					r);
		*/

		// Copy all triangles
		boost::range::copy(
			single_result.triangles(),
			std::back_inserter(
				result->mesh().triangles()));
	}

	// If there were no triangles, we can return
	if(result->mesh().triangles().empty())
		return
			result;

	// Step 2: Calculate the bounding box and the barycenter (we can do
	// that in one pass, luckily)
	result->barycenter() = fcppt::math::vector::null<vector3>();

	vector3
		min_pos =
			result->mesh().triangles().front().vertices[0],
		max_pos =
			min_pos;

	for(
		mesh::triangle_sequence::const_iterator current_tri =
			result->mesh().triangles().begin();
		current_tri != result->mesh().triangles().end();
		++current_tri)
	{
		for(
			triangle::vertex_array::const_iterator current_vertex =
				current_tri->vertices.begin();
			current_vertex != current_tri->vertices.end();
			++current_vertex)
		{
			result->barycenter() += *current_vertex;
			for (vector3::size_type i = 0; i < 3; ++i)
			{
				min_pos.get_unsafe(i) = std::min(min_pos.get_unsafe(i),(*current_vertex).get_unsafe(i));
				max_pos.get_unsafe(i) = std::max(max_pos.get_unsafe(i),(*current_vertex).get_unsafe(i));
			}
		}
	}

	result->bounding_box() =
		box3(
			min_pos,
			fcppt::math::vector::to_dim(
				max_pos - min_pos));

	result->barycenter() /=
		static_cast<scalar>(
			result->mesh().triangles().size() * 3);

	for(
		mesh::triangle_sequence::iterator current_tri =
			result->mesh().triangles().begin();
		current_tri != result->mesh().triangles().end();
		++current_tri)
		for(
			triangle::vertex_array::iterator current_vertex =
				current_tri->vertices.begin();
			current_vertex != current_tri->vertices.end();
			++current_vertex)
			(*current_vertex) -= result->barycenter();

	// If we've got no border, quit now. This happens when the cutting
	// plane doesn't intersect with the fruit at all (we "miss", so to
	// speak)
	if(border.size() < static_cast<vector3_sequence::size_type>(3))
		return
			result;

	fcppt::optional::object<matrix4> const cs(
		make_coordinate_system(
			border,
			epsilon));

	if(!cs.has_value())
		return
			result;

	matrix4 const tcs =
		cs.get_unsafe(); // TODO

	matrix4 const coordinate_transformation =
		fcppt::math::matrix::inverse(
			tcs);

	typedef
	boost::geometry::model::multi_point<
		geometry_vector2
	>
	point_cloud_2d;

	typedef
	boost::geometry::model::ring<
		geometry_vector2
	>
	ring_2d;

	point_cloud_2d reduced;

	reduced.reserve(
		border.size());

	// TODO: map
	for(vector3_sequence::const_iterator i = border.begin(); i != border.end(); ++i)
	{
		vector4 const transformed =
			coordinate_transformation *
			vector4(
				(*i).x(),
				(*i).y(),
				(*i).z(),
				// WATCH OUT: ONLY WORKS WITH THE 1 HERE!
				1.f);

		reduced.push_back(
			geometry_vector2(
				fcppt::math::vector::narrow_cast<
					vector2
				>(
					transformed
				)
			)
		);

		FCPPT_ASSERT_ERROR(
			transformed.z() < epsilon);

		/*
		// Warning: Costly assert!
		if(
			fcppt::math::vector::length(
				vector_narrow<vector3>(
					(*cs) * vector4(reduced.back()[0],reduced.back()[1],0,1)) -
				(*i)) > epsilon)
		{
			std::cout <<
				fcppt::math::vector::length(
					vector_narrow<vector3>(
						(*cs) * vector4(reduced.back()[0],reduced.back()[1],0,1)) -
					(*i)) << "\n";
			std::exit(1);
		}
		*/
	}

	ring_2d convex_hull_result;

	boost::geometry::convex_hull(
		reduced,
		convex_hull_result);

	if(convex_hull_result.size() < static_cast<ring_2d::size_type>(3))
		return
			result;

	geometry_box2 const envelope(
		boost::geometry::return_envelope<
			geometry_box2
		>(
			convex_hull_result
		)
	);

	typedef
	std::vector<vector2>
	texcoord_vector;

	texcoord_vector texcoords;
	texcoords.reserve(
		convex_hull_result.size());

	for(
		auto const &element
		:
		convex_hull_result
	)
		texcoords.push_back(
			(element.base() - envelope.pos())
			/
			envelope.size()
		);

	ring_2d::size_type const triangle_count =
		static_cast<ring_2d::size_type>(
			convex_hull_result.size() - 2u);

	result->mesh().triangles().reserve(
		result->mesh().triangles().size() + triangle_count);

	for(
		ring_2d::size_type current_vertex =
			static_cast<ring_2d::size_type>(
				2);
		current_vertex < convex_hull_result.size();
		++current_vertex)
	{
		result->cross_section().triangles().push_back(
			fruit::triangle(
				{{
					fcppt::math::vector::narrow_cast<vector3>(
						tcs *
						vector4(
							convex_hull_result[0].x(),
							convex_hull_result[0].y(),
							0.f,
							1.f)) - result->barycenter(),
					fcppt::math::vector::narrow_cast<vector3>(
						tcs *
						vector4(
							convex_hull_result[current_vertex-1].x(),
							convex_hull_result[current_vertex-1].y(),
							0.f,
							1.f)) - result->barycenter(),
					fcppt::math::vector::narrow_cast<vector3>(
						tcs *
						vector4(
							convex_hull_result[current_vertex].x(),
							convex_hull_result[current_vertex].y(),
							0.f,
							1.f)) - result->barycenter()}},
				{{
					transform_texcoord(
						texcoords[
							0]),
					transform_texcoord(
						texcoords[
							current_vertex-1]),
					transform_texcoord(
						texcoords[
							current_vertex])}},
				{{
					-input_plane.normal(),
					-input_plane.normal(),
					-input_plane.normal()}}));

		result->mesh().triangles().push_back(
			result->cross_section().triangles().back());

		result->area() =
			fruit::area(
				result->area().get() +
				fruitlib::math::triangle::area(
					result->mesh().triangles().back()));
	}

	return
		result;
}
	cuda_device friend vector4 fast_normalize(const vector4& v) {
		return v * fast_rsqrt_T(v.dot(v));
	}
	cuda_device friend T fast_length(const vector4& v) {
		return fast_sqrt_T(v.dot(v));
	}
	cuda_device friend T length(const vector4& v) {
		return sqrt_T(v.dot(v));
	}
	cuda_device friend T dot(const vector4& v1, const vector4& v2) {
		return v1.dot(v2);
	}
	cuda_device friend vector4 cross(const vector4& v1, const vector4& v2) {
		return v1.cross(v2);
	}