90 lines
2.7 KiB
C
90 lines
2.7 KiB
C
|
/*
|
||
|
Apophysis Plugin
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
|
*/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
double barycentroid_a, barycentroid_b, barycentroid_c, barycentroid_d;
|
||
|
double a, b, c, d;
|
||
|
} Variables;
|
||
|
|
||
|
#include "apoplugin.h"
|
||
|
|
||
|
APO_PLUGIN("barycentroid");
|
||
|
|
||
|
APO_VARIABLES(
|
||
|
VAR_REAL(barycentroid_a, 1.0),
|
||
|
VAR_REAL(barycentroid_b, 0.0),
|
||
|
VAR_REAL(barycentroid_c, 0.0),
|
||
|
VAR_REAL(barycentroid_d, 1.0)
|
||
|
);
|
||
|
|
||
|
int PluginVarPrepare(Variation* vp)
|
||
|
{
|
||
|
// alias
|
||
|
VAR(a) = VAR(barycentroid_a);
|
||
|
VAR(b) = VAR(barycentroid_b);
|
||
|
VAR(c) = VAR(barycentroid_c);
|
||
|
VAR(d) = VAR(barycentroid_d);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
inline double sgn(double v) { return v < 0 ? -1 : v > 0 ? 1 : 0; }
|
||
|
|
||
|
int PluginVarCalc(Variation* vp)
|
||
|
{
|
||
|
// helpers
|
||
|
|
||
|
/* The code is supposed to be fast and you all can read it so I dont
|
||
|
create those aliases for readability in actual code:
|
||
|
|
||
|
v0x = VAR(a)
|
||
|
v0y = VAR(b)
|
||
|
v1x = VAR(c)
|
||
|
v1y = VAR(d)
|
||
|
v2x = FTx
|
||
|
v2y = FTy
|
||
|
*/
|
||
|
|
||
|
// compute dot products
|
||
|
double dot00 = VAR(a) * VAR(a) + VAR(b) * VAR(b); // v0 * v0
|
||
|
double dot01 = VAR(a) * VAR(c) + VAR(b) * VAR(d); // v0 * v1
|
||
|
double dot02 = VAR(a) * FTx + VAR(b) * FTy; // v0 * v2
|
||
|
double dot11 = VAR(c) * VAR(c) + VAR(d) * VAR(d); // v1 * v1
|
||
|
double dot12 = VAR(c) * FTx + VAR(d) * FTy; // v1 * v2
|
||
|
|
||
|
// compute inverse denomiator
|
||
|
double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
||
|
|
||
|
/* now we can pull [u,v] as the barycentric coordinates of the point
|
||
|
P in the triangle [A, B, C]
|
||
|
*/
|
||
|
double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||
|
double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||
|
|
||
|
// now combine with input
|
||
|
double um = sqrt(sqr(u) + sqr(FTx)) * sgn(u);
|
||
|
double vm = sqrt(sqr(v) + sqr(FTy)) * sgn(v);
|
||
|
|
||
|
FPx += VVAR * um;
|
||
|
FPy += VVAR * vm;
|
||
|
FPz += VVAR * FTz; // just pass
|
||
|
|
||
|
return TRUE;
|
||
|
}
|