Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <toonz_plugin.h></toonz_plugin.h>
Toshihiro Shimizu 890ddd
#include <toonz_hostif.h></toonz_hostif.h>
Toshihiro Shimizu 890ddd
#include <toonz_params.h></toonz_params.h>
Toshihiro Shimizu 890ddd
#include <memory></memory>
Toshihiro Shimizu 890ddd
#include <cmath></cmath>
Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
#include "toonz_plugin_helper_rect.h"
Toshihiro Shimizu 890ddd
#include "toonz_plugin_helper_affine.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <utils interf_holder.hpp=""></utils>
Toshihiro Shimizu 890ddd
#include <utils param_traits.hpp=""></utils>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#define RESTRICT
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define RESTRICT __restrict
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" {
Toshihiro Shimizu 890ddd
TOONZ_EXPORT int toonz_plugin_init(toonz::host_interface_t *hostif);
Toshihiro Shimizu 890ddd
TOONZ_EXPORT void toonz_plugin_exit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
toonz::host_interface_t *ifactory_ = NULL;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int toonz_plugin_init(toonz::host_interface_t *hostif)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("toonz_plugin_init()\n");
Toshihiro Shimizu 890ddd
	ifactory_ = hostif;
Toshihiro Shimizu 890ddd
	return TOONZ_OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void toonz_plugin_exit()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("toonz_plugin_exit()\n");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void do_compute(toonz::node_handle_t node, const toonz::rendering_setting_t *rs, double frame, toonz::tile_handle_t tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("do_compute(): node:%p tile:%p frame:%g\n", node, tile, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	auto nodeif = grab_interf<toonz::node_interface_t>(TOONZ_UUID_NODE);</toonz::node_interface_t>
Toshihiro Shimizu 890ddd
	if (nodeif) {
Toshihiro Shimizu 890ddd
		void *param = NULL;
Toshihiro Shimizu 890ddd
		int r = nodeif->get_param(node, "p3rd", ¶m);
Toshihiro Shimizu 890ddd
		if (r == TOONZ_OK) {
Toshihiro Shimizu 890ddd
			printf("do_compute: get param: p:%p\n", param);
Toshihiro Shimizu 890ddd
			auto pif = grab_interf<toonz::param_interface_t>(TOONZ_UUID_PARAM);</toonz::param_interface_t>
Toshihiro Shimizu 890ddd
			if (pif) {
Toshihiro Shimizu 890ddd
				int type, counts;
Toshihiro Shimizu 890ddd
				pif->get_type(param, frame, &type, &counts);
Toshihiro Shimizu 890ddd
				printf("do_compute: get value type:%d\n", type);
Toshihiro Shimizu 890ddd
				toonz_param_traits_point_t::iovaluetype v;
Toshihiro Shimizu 890ddd
				pif->get_value(param, frame, &counts, &v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				printf("do_compute: value:[%g, %g]\n", v.x, v.y);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			printf("do_compute: error to get param:0x%x\n", r);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	auto tileif = grab_interf<toonz::tile_interface_t>(TOONZ_UUID_TILE);</toonz::tile_interface_t>
Toshihiro Shimizu 890ddd
	if (tileif) {
Toshihiro Shimizu 890ddd
		toonz::rect_t rect;
Toshihiro Shimizu 890ddd
		tileif->get_rectangle(tile, &rect);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/* evaluate the fx */
Toshihiro Shimizu 890ddd
		int lx = rect.x1 - rect.x0;
Toshihiro Shimizu 890ddd
		int ly = rect.y1 - rect.y0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToonzAffine mat(rs->affine);
Toshihiro Shimizu 890ddd
		ToonzAffine invmat = mat.inv();
Toshihiro Shimizu 890ddd
		ToonzPoint p = invmat * ToonzPoint(rect.x0, rect.y0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int dstride = 0;
Toshihiro Shimizu 890ddd
		tileif->get_raw_stride(tile, &dstride);
Toshihiro Shimizu 890ddd
		int delement_type = 0;
Toshihiro Shimizu 890ddd
		tileif->get_element_type(tile, &delement_type);
Toshihiro Shimizu 890ddd
		uint8_t *daddr = NULL;
Toshihiro Shimizu 890ddd
		tileif->get_raw_address_unsafe(tile, reinterpret_cast<void **="">(&daddr));</void>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		printf("-+ lx:%d ly:%d\n", lx, ly);
Toshihiro Shimizu 890ddd
		printf("-+ px:%g py:%g\n", p.x, p.y);
Toshihiro Shimizu 890ddd
		printf(" + dst rect(%g, %g, %g, %g)\n", rect.x0, rect.y0, rect.x1, rect.y1);
Toshihiro Shimizu 890ddd
		printf(" + dst tile: addr:%p stride:%d type:%d\n", daddr, dstride, delement_type);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// need compatibility check for formats
Toshihiro Shimizu 890ddd
		for (int i = 0; i < ly; i++) {
Toshihiro Shimizu 890ddd
			uint32_t *ptr = reinterpret_cast<uint32_t *="">(daddr + i * dstride);</uint32_t>
Toshihiro Shimizu 890ddd
			/* [rx, ry] は effect の面内を描くベクトル. 半径 r 円の中心が [0, 0] で、 [-lx/2, -ly/2]-[lx/2, ly/2]
Toshihiro Shimizu 890ddd
			   [j, i] は dst のスキャンラインのベクトルで [0, 0]-[lx, ly] */
Toshihiro Shimizu 890ddd
			double rx = p.x;
Toshihiro Shimizu 890ddd
			double ry = p.y;
Toshihiro Shimizu 890ddd
			for (int j = 0; j < lx; j++) {
Toshihiro Shimizu 890ddd
				double r = std::sqrt(rx * rx + ry * ry);
Toshihiro Shimizu 890ddd
				double k = 0;
Toshihiro Shimizu 890ddd
				if (r < 64)
Toshihiro Shimizu 890ddd
					k = 1;
Toshihiro Shimizu 890ddd
				uint8_t c = (uint8_t)(k * 255);
Toshihiro Shimizu 890ddd
				*(ptr + j) = 0xff000000 | (c << 16) | (c << 8) | c;
Toshihiro Shimizu 890ddd
				/* hor advance */
Toshihiro Shimizu 890ddd
				rx += invmat.a11;
Toshihiro Shimizu 890ddd
				ry += invmat.a21;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			/* vert advance */
Toshihiro Shimizu 890ddd
			p.x += invmat.a12;
Toshihiro Shimizu 890ddd
			p.y += invmat.a22;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int do_get_bbox(toonz::node_handle_t node, const toonz::rendering_setting_t *rs, double frame, toonz::rect_t *rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("do_get_bbox(): node:%p\n", node);
Toshihiro Shimizu 890ddd
	bool modified = false;
Toshihiro Shimizu 890ddd
/* 円の周辺の黒いマスク部分が bbox に相当する:
Toshihiro Shimizu 890ddd
	   コンサバには無限に大きな矩形を返すのが最もコンサバな方法だが、 rendering_setting_t の affine 変換行列を用いてよりよい予測をすることもできる.
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
	/* too concervative */
Toshihiro Shimizu 890ddd
	rect->x0 = -std::numeric_limits< double >::max();
Toshihiro Shimizu 890ddd
	rect->y0 = -std::numeric_limits< double >::max();
Toshihiro Shimizu 890ddd
	rect->x1 = std::numeric_limits< double >::max();
Toshihiro Shimizu 890ddd
	rect->y1 = std::numeric_limits< double >::max();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
	/* too aggressive */
Toshihiro Shimizu 890ddd
	rect->x0 = -64;
Toshihiro Shimizu 890ddd
	rect->y0 = -64;
Toshihiro Shimizu 890ddd
	rect->x1 = 64;
Toshihiro Shimizu 890ddd
	rect->y1 = 64;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	/* more reasonable than above */
Toshihiro Shimizu 890ddd
	ToonzRect r(-64, -64, 64, 64);
Toshihiro Shimizu 890ddd
	ToonzRect bbox = ToonzAffine(rs->affine) * r;
Toshihiro Shimizu 890ddd
	rect->x0 = bbox.x0;
Toshihiro Shimizu 890ddd
	rect->y0 = bbox.y0;
Toshihiro Shimizu 890ddd
	rect->x1 = bbox.x1;
Toshihiro Shimizu 890ddd
	rect->y1 = bbox.y1;
Toshihiro Shimizu 890ddd
	return modified;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
param_desc_t params0_[] = {
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_double_t>("p1st", "", {1.0 /* default */, -1.0 /* min */, 1.0 /* max */}),</traits_double_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_range_t>("p2nd", "", {{48.0, 64.0} /* default */, {0.0, 180.0} /* min-max */}),</traits_range_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_point_t>("p3rd", "", {{0, 0} /* default */, {-10, 10} /* min */, {-200, +200} /* max */}),</traits_point_t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
param_desc_t params1_[] = {
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_double_t>("g1st", "", {1.0 /* default */, -1.0 /* min */, 1.0 /* max */}),</traits_double_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_range_t>("g2nd", "", {{48.0, 64.0} /* default */, {0.0, 180.0} /* min-max */}),</traits_range_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_point_t>("g3rd", "", {{1, 1} /* default */, {-10, 10} /* min */, {-200, +200} /* max */}),</traits_point_t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
param_desc_t params2_[] = {
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_double_t>("pp1st", "", {1.0 /* default */, -1.0 /* min */, 1.0 /* max */}),</traits_double_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_range_t>("pp2nd", "", {{48.0, 64.0} /* default */, {0.0, 90.0} /* min-max */}),</traits_range_t>
Toshihiro Shimizu 890ddd
	param_desc_ctor<traits_point_t>("pp3rd", "", {{1, 1} /* default */, {-10, 10} /* min */, {-200, +200} /* max */}),</traits_point_t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
toonz_param_group_t groups0_[] = {
Toshihiro Shimizu 890ddd
	param_group_ctor("First Group", sizeof(params0_) / sizeof(param_desc_t), params0_),
Toshihiro Shimizu 890ddd
	param_group_ctor("Second Group", sizeof(params1_) / sizeof(param_desc_t), params1_),
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
toonz_param_group_t groups1_[] = {
Toshihiro Shimizu 890ddd
	param_group_ctor("Third Group", sizeof(params2_) / sizeof(param_desc_t), params2_),
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
toonz_param_page_t pages_[] = {
Toshihiro Shimizu 890ddd
	param_page_ctor("Main Page", sizeof(groups0_) / sizeof(toonz_param_group_t), groups0_),
Toshihiro Shimizu 890ddd
	param_page_ctor("Sub Page", sizeof(groups1_) / sizeof(toonz_param_group_t), groups1_),
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int node_setup(toonz::node_handle_t node)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	auto setup = grab_interf<toonz::setup_interface_t>(TOONZ_UUID_SETUP);</toonz::setup_interface_t>
Toshihiro Shimizu 890ddd
	if (setup) {
Toshihiro Shimizu 890ddd
		int errcode = 0;
Toshihiro Shimizu 890ddd
		void *entry = NULL;
Toshihiro Shimizu 890ddd
		int ret = setup->set_parameter_pages_with_error(node, 2, pages_, &errcode, &entry);
Toshihiro Shimizu 890ddd
		if (ret) {
Toshihiro Shimizu 890ddd
			printf("setup error:0x%x reason:0x%x entry:%p\n", ret, errcode, entry);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		setup->add_input_port(node, "IPort", TOONZ_PORT_TYPE_RASTER);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int node_create(toonz::node_handle_t node)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("create(): node:%p\n", node);
Toshihiro Shimizu 890ddd
	return TOONZ_OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int node_destroy(toonz::node_handle_t node)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("destroy():node:%p\n", node);
Toshihiro Shimizu 890ddd
	return TOONZ_OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int can_handle(toonz_node_handle_t node, const toonz_rendering_setting_t *rs, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s:\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
	/* geometric plugin のように Bounding Box が自明の場合、 Skew などの変換の影響でフルスクリーン効果のような大きな Bouding Box が
Toshihiro Shimizu 890ddd
	   過剰に大きくなってしまうことがある. これを防ぐには非ゼロを返すこと.
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
	return 1; /* non zero is 'true' */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
size_t get_memory_requirement(toonz_node_handle_t node, const toonz_rendering_setting_t *rs, double frame, const toonz_rect_t *rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s:\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
	return TOONZ_OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void on_new_frame(toonz_node_handle_t node, const toonz_rendering_setting_t *rs, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s:\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void on_end_frame(toonz_node_handle_t node, const toonz_rendering_setting_t *rs, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("%s:\n", __FUNCTION__);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
toonz_nodal_rasterfx_handler_t_ toonz_plugin_node_handler =
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		{1, 0},					//	ver
Toshihiro Shimizu 890ddd
		do_compute,				//	do_compute
Toshihiro Shimizu 890ddd
		do_get_bbox,			//	do_get_bbox
Toshihiro Shimizu 890ddd
		can_handle,				//	can_handle
Toshihiro Shimizu 890ddd
		get_memory_requirement, //	get_memory_requirement
Toshihiro Shimizu 890ddd
		on_new_frame,			//	on_new_frame
Toshihiro Shimizu 890ddd
		on_end_frame,			//	on_end_frame
Toshihiro Shimizu 890ddd
		node_create,			//	create
Toshihiro Shimizu 890ddd
		node_destroy,			//	destroy
Toshihiro Shimizu 890ddd
		node_setup};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" {
Toshihiro Shimizu 890ddd
TOONZ_PLUGIN_PROBE_BEGIN(TOONZ_IF_VER(1, 0))
Toshihiro Shimizu 890ddd
TOONZ_PLUGIN_PROBE_DEFINE(TOONZ_PLUGIN_VER(1, 0), "geom-plugin" /* name */, "dwango" /* vendor */, "geom.plugin" /* identifier */, "a geom plugin for test", "http://dwango.co.jp/", TOONZ_PLUGIN_CLASS_POSTPROCESS_SLAB | TOONZ_PLUGIN_CLASS_MODIFIER_GEOMETRIC, &toonz_plugin_node_handler)
Toshihiro Shimizu 890ddd
TOONZ_PLUGIN_PROBE_END;
Toshihiro Shimizu 890ddd
}