Blame synfig-core/src/synfig/rendering/primitive/mesh.cpp

3c2463
/* === S Y N F I G ========================================================= */
248685
/*!	\file synfig/rendering/primitive/mesh.cpp
3c2463
**	\brief Mesh
3c2463
**
3c2463
**	$Id$
3c2463
**
3c2463
**	\legal
3c2463
**	......... ... 2015 Ivan Mahonin
3c2463
**
3c2463
**	This package is free software; you can redistribute it and/or
3c2463
**	modify it under the terms of the GNU General Public License as
3c2463
**	published by the Free Software Foundation; either version 2 of
3c2463
**	the License, or (at your option) any later version.
3c2463
**
3c2463
**	This package is distributed in the hope that it will be useful,
3c2463
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
3c2463
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3c2463
**	General Public License for more details.
3c2463
**	\endlegal
3c2463
*/
3c2463
/* ========================================================================= */
3c2463
3c2463
/* === H E A D E R S ======================================================= */
3c2463
3c2463
#ifdef USING_PCH
3c2463
#	include "pch.h"
3c2463
#else
3c2463
#ifdef HAVE_CONFIG_H
3c2463
#	include <config.h></config.h>
3c2463
#endif
3c2463
3c2463
#include "mesh.h"
3c2463
3c2463
#endif
3c2463
3c2463
using namespace synfig;
248685
using namespace rendering;
3c2463
3c2463
/* === M A C R O S ========================================================= */
3c2463
3c2463
/* === G L O B A L S ======================================================= */
3c2463
3c2463
/* === P R O C E D U R E S ================================================= */
3c2463
3c2463
/* === M E T H O D S ======================================================= */
3c2463
8c834e
Mesh::Mesh():
8c834e
	resolution_transfrom_calculated(false) { }
8c834e
8c834e
void
8c834e
Mesh::assign(const Mesh &other) {
8c834e
	vertices = other.vertices;
8c834e
	triangles = other.triangles;
8c834e
	
8c834e
	// other mesh is constant, so we need to lock mutexes for read the relolution data
8c834e
	// see comment for calculate_resolution_transfrom() declaration
8c834e
	{
Rodolfo Ribeiro Gomes d18249
		std::lock_guard<std::mutex> lock(other.resolution_transfrom_read_mutex);</std::mutex>
8c834e
		resolution_transfrom_calculated = other.resolution_transfrom_calculated;
8c834e
		target_rectangle = other.target_rectangle;
8c834e
		source_rectangle = other.source_rectangle;
8c834e
		resolution_transfrom = other.resolution_transfrom;
8c834e
	}
8c834e
}
8c834e
248685
void
8c834e
Mesh::clear()
e93eb5
{
8c834e
	vertices.clear();
8c834e
	triangles.clear();
8c834e
	reset_resolution_transfrom();
8c834e
}
9af60c
8c834e
void
8c834e
Mesh::reset_resolution_transfrom()
8c834e
	{ resolution_transfrom_calculated = false; }
8c834e
2c1524
Rect
2c1524
Mesh::calc_target_rectangle() const
2c1524
{
2c1524
	if (vertices.empty()) return Rect::zero();
2c1524
	Rect target_rectangle = Rect(vertices[0].position);
2c1524
	for(std::vector<vertex>::const_iterator i = vertices.begin(); i != vertices.end(); ++i)</vertex>
2c1524
		target_rectangle.expand(i->position);
2c1524
	return target_rectangle;
2c1524
}
2c1524
2c1524
Rect
2c1524
Mesh::calc_target_rectangle(const Matrix &transform_matrix) const
2c1524
{
2c1524
	if (vertices.empty()) return Rect::zero();
2c1524
	Rect target_rectangle = Rect(transform_matrix.get_transformed(vertices[0].position));
2c1524
	for(std::vector<vertex>::const_iterator i = vertices.begin(); i != vertices.end(); ++i)</vertex>
2c1524
		target_rectangle.expand( transform_matrix.get_transformed(i->position) );
2c1524
	return target_rectangle;
2c1524
}
2c1524
2c1524
2c1524
Rect
2c1524
Mesh::calc_source_rectangle() const
2c1524
{
2c1524
	if (vertices.empty()) return Rect::zero();
2c1524
	Rect source_rectangle = Rect(vertices[0].position);
2c1524
	for(std::vector<vertex>::const_iterator i = vertices.begin(); i != vertices.end(); ++i)</vertex>
2c1524
		source_rectangle.expand(i->position);
2c1524
	return source_rectangle;
2c1524
}
2c1524
Rect
2c1524
Mesh::calc_source_rectangle(const Matrix &transform_matrix) const
2c1524
{
2c1524
	if (vertices.empty()) return Rect::zero();
2c1524
	Rect source_rectangle = Rect(transform_matrix.get_transformed(vertices[0].tex_coords));
2c1524
	for(std::vector<vertex>::const_iterator i = vertices.begin(); i != vertices.end(); ++i)</vertex>
2c1524
		source_rectangle.expand( transform_matrix.get_transformed(i->tex_coords) );
2c1524
	return source_rectangle;
2c1524
}
2c1524
8c834e
void
8c834e
Mesh::calculate_resolution_transfrom_no_lock(bool force) const
8c834e
{
8c834e
	if (resolution_transfrom_calculated && !force)
8c834e
		return;
e48a26
	// TODO:
9af60c
	resolution_transfrom.set_identity();
2c1524
	target_rectangle = calc_target_rectangle();
2c1524
	source_rectangle = calc_source_rectangle();
8c834e
	resolution_transfrom_calculated = true;
8c834e
}
8c834e
8c834e
void
8c834e
Mesh::calculate_resolution_transfrom(bool force) const
8c834e
{
Rodolfo Ribeiro Gomes d18249
	std::lock_guard<std::mutex> lock(resolution_transfrom_read_mutex);</std::mutex>
8c834e
	calculate_resolution_transfrom_no_lock(force);
8c834e
}
8c834e
8c834e
Matrix2
8c834e
Mesh::get_resolution_transfrom() const
8c834e
{
Rodolfo Ribeiro Gomes d18249
	std::lock_guard<std::mutex> lock(resolution_transfrom_read_mutex);</std::mutex>
8c834e
	calculate_resolution_transfrom_no_lock();
8c834e
	return resolution_transfrom;
8c834e
}
8c834e
8c834e
Rect
8c834e
Mesh::get_target_rectangle() const
8c834e
{
Rodolfo Ribeiro Gomes d18249
	std::lock_guard<std::mutex> lock(resolution_transfrom_read_mutex);</std::mutex>
8c834e
	calculate_resolution_transfrom_no_lock();
8c834e
	return target_rectangle;
8c834e
}
8c834e
8c834e
Rect
8c834e
Mesh::get_source_rectangle() const
8c834e
{
Rodolfo Ribeiro Gomes d18249
	std::lock_guard<std::mutex> lock(resolution_transfrom_read_mutex);</std::mutex>
8c834e
	calculate_resolution_transfrom_no_lock();
8c834e
	return source_rectangle;
8c834e
}
8c834e
8c834e
bool
8c834e
Mesh::transform_coord_world_to_texture(
8c834e
	const Vector &src,
8c834e
	Vector &dest,
8c834e
	const Vector &p0,
8c834e
	const Vector &t0,
8c834e
	const Vector &p1,
8c834e
	const Vector &t1,
8c834e
	const Vector &p2,
8c834e
	const Vector &t2 )
8c834e
{
8c834e
	// is point inside triangle?
8c834e
	Matrix matrix_of_base_triangle(
8c834e
		p1[0]-p0[0], p1[1]-p0[1], 0.0,
8c834e
		p2[0]-p0[0], p2[1]-p0[1], 0.0,
8c834e
		p0[0], p0[1], 1.0 );
8c834e
	if (!matrix_of_base_triangle.is_invertible()) return false;
8c834e
8c834e
	matrix_of_base_triangle.invert();
8c834e
	Vector v = matrix_of_base_triangle.get_transformed(src);
8c834e
	if (v[0] < 0.0 || v[0] > 1.0
8c834e
	 || v[1] < 0.0 || v[1] > 1.0
8c834e
	 || v[0] + v[1] > 1.0) return false;
8c834e
8c834e
	// get coords at texture
8c834e
	Matrix matrix_of_texture_triangle(
8c834e
		t1[0]-t0[0], t1[1]-t0[1], 0.0,
8c834e
		t2[0]-t0[0], t2[1]-t0[1], 0.0,
8c834e
		t0[0], t0[1], 1.0 );
8c834e
	dest = matrix_of_texture_triangle.get_transformed(v);
8c834e
	return true;
8c834e
}
8c834e
8c834e
bool
8c834e
Mesh::transform_coord_world_to_texture(const Vector &src, Vector &dest) const
8c834e
{
8c834e
	// process triangles backward
8c834e
	for(TriangleList::const_reverse_iterator ri = triangles.rbegin(); ri != triangles.rend(); ++ri)
8c834e
		if (transform_coord_world_to_texture(
8c834e
			src,
8c834e
			dest,
8c834e
			vertices[ri->vertices[0]].position,
8c834e
			vertices[ri->vertices[0]].tex_coords,
8c834e
			vertices[ri->vertices[1]].position,
8c834e
			vertices[ri->vertices[1]].tex_coords,
8c834e
			vertices[ri->vertices[2]].position,
8c834e
			vertices[ri->vertices[2]].tex_coords
8c834e
		))
8c834e
			return true;
8c834e
	return false;
8c834e
}
8c834e
8c834e
bool
8c834e
Mesh::transform_coord_texture_to_world(const Vector &src, Vector &dest) const
8c834e
{
8c834e
	// process triangles backward
8c834e
	for(TriangleList::const_reverse_iterator ri = triangles.rbegin(); ri != triangles.rend(); ++ri)
8c834e
		if (transform_coord_texture_to_world(
8c834e
			src,
8c834e
			dest,
8c834e
			vertices[ri->vertices[0]].position,
8c834e
			vertices[ri->vertices[0]].tex_coords,
8c834e
			vertices[ri->vertices[1]].position,
8c834e
			vertices[ri->vertices[1]].tex_coords,
8c834e
			vertices[ri->vertices[2]].position,
8c834e
			vertices[ri->vertices[2]].tex_coords
8c834e
		))
8c834e
			return true;
8c834e
	return false;
3c2463
}
3c2463
3c2463
/* === E N T R Y P O I N T ================================================= */