On 20/03/2014 at 13:03, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 13
Platform: Windows ;
Language(s) : C++ ;
---------
Hi,
I was talking with PerAnders on CGTalk about drawing splines in Shader plugins. And he gave me a link to this site that has Renderman code examples.
And I'm having some trouble converting it to C4D.
http://www.hosok2.com/project/st/bezierCurve_kitty.sl.txt
Renderman shaders use the global variables s&t the same way we use cd->p.x & cd->p.y in C4D shaders. At least that's how I think it works.
But I can't figure out how to use: ChannelData *cd in these custom methods to replace the s&t Renderman variables.
C4D is crashing on me if I try to use them in those custom methods. Or anywhere other than the Output() method.
This is my entire shader plugin code. Based on that RM example.
Does anyone know how I can convert the s&t variables to work in C4D?
#include "c4d.h"
#include "c4d_symbols.h"
#include "myshader.h"
#define PLUGIN_ID 1000000
class MyShader : public ShaderData
{
private:
Real offset;
Bool enabled;
Real octives;
Real bp[288];
public:
virtual Bool Init(GeListNode *node);
virtual Vector Output(BaseShader *chn, ChannelData *cd);
virtual INITRENDERRESULT InitRender(BaseShader *sh, const InitRenderStruct &irs);
virtual void FreeRender(BaseShader *sh);
static NodeData *Alloc(void) { return gNew MyShader; }
};
Real isInLine(Real p1x, Real p1y, Real p2x, Real p2y, Real thickness)
{
ChannelData *cd = NULL; //In RM shaders. s&t are built-in global variables equal to: cd->p.x & cd->p.y in the C4D SDK
Real s = cd->p.x; //But C4D crashes if I use ChannelData here to try to convert the RM variables s&t to C4D compatible values!!!
Real t = cd->p.y; //How can I convert s&t in this RM code to work in a C4D shader plugin?
Real out = 0;
Real halfThickness = thickness/2;
Real ang = 0;
if(p2x-p1x == 0)ang = 0;
if(p2y-p1y == 0)ang = 90;
else ang = atan((p2x-p1x)/(p2y-p1y));
Real centerLineT = (t - p1y) * tan(ang);
Real s1 = s - p1x;
Real cuttingSA = ((1-s +p2x )*tan(ang) - tan(ang))+p2y;
Real cuttingSB = ((1-s +p1x )*tan(ang) - tan(ang))+p1y;
Real lineboarderA= halfThickness / cos(180-ang) + centerLineT;
Real lineboarderB= centerLineT-(halfThickness / cos(180-ang));
if(s1>lineboarderA && s1<lineboarderB)
{
if(p1y - p2y>0)
{
if(t>cuttingSA && t<cuttingSB) out = 1;
else
{
if(t<cuttingSA && t>cuttingSB) out = 1;
}
}
}
return out;
}
Real isInOval(Real x, Real y, Real radius)
{
ChannelData *cd = NULL; //In RM shaders. s&t are built-in global variables equal to: cd->p.x & cd->p.y in the C4D SDK
Real s = cd->p.x; //But C4D crashes if I use ChannelData here to try to convert the RM variables s&t to C4D compatible values!!!
Real t = cd->p.y; //How can I convert s&t in this RM code to work in a C4D shader plugin?
Real inOval = 0;
if(pow(s-x,2)+pow(t-y,2) < pow(radius,2))inOval = 1;
return inOval;
}
Real isInLine(Real x, Real y, Real thickness)
{
return 1;
}
Real bezier(Real i, Real a, Real b, Real c, Real d)
{
Real B = pow((1-i),3)*a + 3*i*pow((1-i),2) * b + 3*pow(i,2)*(1-i)*c + pow(i,3)*d;
return B;
}
Real isInbezier(Real p0[2],Real p1[2], Real p2[2], Real p3[2], Real thickness, Real pointRate)
{
Real out = 0.5;
Real b[2];
Real prevX = 0;
Real prevY = 0;
Real i=0;
Real addV = pointRate;
for(i = 0; i < 1; i += addV)
{
b[0] = bezier(i,p0[0],p1[0],p2[0],p3[0]);
b[1] = bezier(i,p0[1],p1[1],p2[1],p3[1]);
if(isInOval(b[0],b[1],thickness)) out = 1;
if( i != 0)
{
prevX = bezier(i-addV,p0[0],p1[0],p2[0],p3[0]);
prevY = bezier(i-addV,p0[1],p1[1],p2[1],p3[1]);
if(isInLine(b[0],b[1],prevX,prevY,thickness * 2))out = 1;
}
}
//Last Point
if(isInOval(p3[0],p3[1],thickness)) out = 1;
if(isInLine(p3[0],p3[1],b[0],b[1],thickness * 2)) out = 1;
return out;
}
Bool MyShader::Init(GeListNode *node)
{
BaseContainer *data = ((BaseShader* )node)->GetDataInstance();
data->SetReal(OFFSET, 0.5);
data->SetReal(OCTIVES, 0);
data->SetBool(ON_OFF, FALSE);
///////////////////////Data Block//////////////////////////
bp[0] = 0.357295;bp[1] = 0.307384;bp[2] = 0.319145;bp[3] = 0.291199;bp[4] = 0.248626;bp[5] = 0.262298;bp[6] = 0.223193;bp[7] = 0.283107;
bp[8] = 0.223193;bp[9] = 0.283107;bp[10] = 0.197759;bp[11] = 0.303916;bp[12] = 0.181575;bp[13] = 0.369812;bp[14] = 0.216256;bp[15] = 0.426458;
bp[16] = 0.467121;bp[17] = 0.294667;bp[18] = 0.423191;bp[19] = 0.290043;bp[20] = 0.380416;bp[21] = 0.294667;bp[22] = 0.357295;bp[23] = 0.307384;
bp[24] = 0.230129;bp[25] = 0.406804;bp[26] = 0.207008;bp[27] = 0.45189;bp[28] = 0.166546;bp[29] = 0.538594;bp[30] = 0.211632;bp[31] = 0.641484;
bp[32] = 0.211632;bp[33] = 0.641484;bp[34] = 0.256718;bp[35] = 0.744374;bp[36] = 0.373482;bp[37] = 0.765181;bp[38] = 0.515675;bp[39] = 0.755933;
bp[40] = 0.515675;bp[41] = 0.755933;bp[42] = 0.65787;bp[43] = 0.746685;bp[44] = 0.760759;bp[45] = 0.709693;bp[46] = 0.787349;bp[47] = 0.622988;
bp[48] = 0.787349;bp[49] = 0.622988;bp[50] = 0.813937;bp[51] = 0.536283;bp[52] = 0.805845;bp[53] = 0.468076;bp[54] = 0.761915;bp[55] = 0.413741;
bp[56] = 0.586759;bp[57] = 0.299223;bp[58] = 0.570023;bp[59] = 0.277627;bp[60] = 0.548427;bp[61] = 0.288424;bp[62] = 0.540868;bp[63] = 0.304081;
bp[64] = 0.540868;bp[65] = 0.304081;bp[66] = 0.533307;bp[67] = 0.319739;bp[68] = 0.534929;bp[69] = 0.343494;bp[70] = 0.567862;bp[71] = 0.344574;
bp[72] = 0.686642;bp[73] = 0.341335;bp[74] = 0.706078;bp[75] = 0.335396;bp[76] = 0.723894;bp[77] = 0.348894;bp[78] = 0.720656;bp[79] = 0.36671;
bp[80] = 0.720656;bp[81] = 0.36671;bp[82] = 0.717418;bp[83] = 0.384527;bp[84] = 0.693121;bp[85] = 0.395325;bp[86] = 0.677465;bp[87] = 0.373729;
bp[88] = 0.4804;bp[89] = 0.375349;bp[90] = 0.503614;bp[91] = 0.395865;bp[92] = 0.545728;bp[93] = 0.398565;bp[94] = 0.578122;bp[95] = 0.373189;
bp[96] = 0.509013;bp[97] = 0.221477;bp[98] = 0.460964;bp[99] = 0.26197;bp[100] = 0.457184;bp[101] = 0.354832;bp[102] = 0.4804;bp[103] = 0.375349;
bp[104] = 0.617535;bp[105] = 0.285726;bp[106] = 0.600799;bp[107] = 0.241994;bp[108] = 0.562387;bp[109] = 0.176501;bp[110] = 0.509014;bp[111] = 0.221477;
bp[112] = 0.674222;bp[113] = 0.312181;bp[114] = 0.699599;bp[115] = 0.290045;bp[116] = 0.75899;bp[117] = 0.278707;bp[118] = 0.777884;bp[119] = 0.305162;
bp[120] = 0.777884;bp[121] = 0.305162;bp[122] = 0.79678;bp[123] = 0.331617;bp[124] = 0.787601;bp[125] = 0.420161;bp[126] = 0.719034;bp[127] = 0.443376;
bp[128] = 0.719034;bp[129] = 0.443376;bp[130] = 0.685665;bp[131] = 0.454674;bp[132] = 0.661805;bp[133] = 0.408283;bp[134] = 0.655866;bp[135] = 0.394786;
bp[136] = 0.607277;bp[137] = 0.264669;bp[138] = 0.644529;bp[139] = 0.250632;bp[140] = 0.703283;bp[141] = 0.216927;bp[142] = 0.730914;bp[143] = 0.233355;
bp[144] = 0.730914;bp[145] = 0.233355;bp[146] = 0.750891;bp[147] = 0.245232;bp[148] = 0.755209;bp[149] = 0.291664;bp[150] = 0.755209;bp[151] = 0.291664;
bp[152] = 0.634107;bp[153] = 0.396369;bp[154] = 0.681664;bp[155] = 0.390094;bp[156] = 0.706689;bp[157] = 0.326596;bp[158] = 0.653755;bp[159] = 0.293313;
bp[160] = 0.576765;bp[161] = 0.318174;bp[162] = 0.559921;bp[163] = 0.355868;bp[164] = 0.576365;bp[165] = 0.403988;bp[166] = 0.634107;bp[167] = 0.396369;
bp[168] = 0.653755;bp[169] = 0.293313;bp[170] = 0.619208;bp[171] = 0.27159;bp[172] = 0.590079;bp[173] = 0.288375;bp[174] = 0.576765;bp[175] = 0.318174;
bp[176] = 0.241038;bp[177] = 0.576052;bp[178] = 0.204851;bp[179] = 0.574286;bp[180] = 0.154984;bp[181] = 0.57782;bp[182] = 0.121444;bp[183] = 0.589734;
bp[184] = 0.248541;bp[185] = 0.633865;bp[186] = 0.211471;bp[187] = 0.638719;bp[188] = 0.178373;bp[189] = 0.653724;bp[190] = 0.164251;bp[191] = 0.662109;
bp[192] = 0.289583;bp[193] = 0.679759;bp[194] = 0.266635;bp[195] = 0.690792;bp[196] = 0.229565;bp[197] = 0.706681;bp[198] = 0.211913;bp[199] = 0.728745;
bp[200] = 0.504;bp[201] = 0.657912;bp[202] = 0.5445;bp[203] = 0.657412;bp[204] = 0.541;bp[205] = 0.616912;bp[206] = 0.505;bp[207] = 0.618912;
bp[208] = 0.505;bp[209] = 0.618912;bp[210] = 0.473984;bp[211] = 0.620635;bp[212] = 0.4635;bp[213] = 0.658412;bp[214] = 0.504;bp[215] = 0.657912;
bp[216] = 0.755;bp[217] = 0.528912;bp[218] = 0.7865;bp[219] = 0.516412;bp[220] = 0.84;bp[221] = 0.508912;bp[222] = 0.877;bp[223] = 0.512912;
bp[224] = 0.7705;bp[225] = 0.582912;bp[226] = 0.7915;bp[227] = 0.582912;bp[228] = 0.839;bp[229] = 0.586912;bp[230] = 0.8605;bp[231] = 0.592412;
bp[232] = 0.7475;bp[233] = 0.643412;bp[234] = 0.7795;bp[235] = 0.650912;bp[236] = 0.8165;bp[237] = 0.656412;bp[238] = 0.8455;bp[239] = 0.673412;
bp[240] = 0.668582;bp[241] = 0.591615;bp[242] = 0.671942;bp[243] = 0.57873;bp[244] = 0.675023;bp[245] = 0.556324;bp[246] = 0.649815;bp[247] = 0.554643;
bp[248] = 0.637211;bp[249] = 0.594696;bp[250] = 0.645613;bp[251] = 0.612342;bp[252] = 0.665071;bp[253] = 0.605071;bp[254] = 0.668581;bp[255] = 0.591615;
bp[256] = 0.649815;bp[257] = 0.554643;bp[258] = 0.636574;bp[259] = 0.55376;bp[260] = 0.626062;bp[261] = 0.571282;bp[262] = 0.637211;bp[263] = 0.594696;
bp[264] = 0.360082;bp[265] = 0.608615;bp[266] = 0.363442;bp[267] = 0.59573;bp[268] = 0.366523;bp[269] = 0.573324;bp[270] = 0.341315;bp[271] = 0.571643;
bp[272] = 0.328711;bp[273] = 0.611696;bp[274] = 0.337113;bp[275] = 0.629342;bp[276] = 0.356571;bp[277] = 0.622071;bp[278] = 0.360081;bp[279] = 0.608615;
bp[280] = 0.341315;bp[281] = 0.571643;bp[282] = 0.328074;bp[283] = 0.57076;bp[284] = 0.317562;bp[285] = 0.588282;bp[286] = 0.328711;bp[287] = 0.611696;
return TRUE;
}
INITRENDERRESULT MyShader::InitRender(BaseShader *sh, const InitRenderStruct &irs)
{
BaseContainer *data = sh->GetDataInstance();
offset = data->GetReal(OFFSET);
octives = data->GetReal(OCTIVES);
enabled = data->GetBool(ON_OFF);
return INITRENDERRESULT_OK;
}
Vector MyShader::Output(BaseShader *chn, ChannelData *cd)
{
Vector colors;
Real px = cd->p.x;
Real py= cd->p.y;
Real opacity = 0.3;
Real thickness = .5;
Real pointRate = 1;
for(LONG i=0; i<sizeof(bp); i += 8)
{
Real p1[2],p2[2],p3[2],p4[2];
p1[0] = bp[i];
p1[1] = bp[i+1];
p2[0] = bp[i+2];
p2[1] = bp[i+3];
p3[0] = bp[i+4];
p3[1] = bp[i+5];
p4[0] = bp[i+6];
p4[1] = bp[i+7];
if(isInbezier(p1,p2,p3,p4,thickness,pointRate) == 1) opacity = 1;
}
//These are RM opacity and color variables
//Oi = Os * opacity;
//Ci = Cs * Oi;
//I have to somehow convert them into C4D compatible variables
//I'm still not sure how to do that properly??
Vector Oi = opacity;
colors = colors * Oi;
return colors;
}
void MyShader::FreeRender(BaseShader *sh)
{
}
Bool RegisterShaderPlugin(void)
{
return RegisterShaderPlugin(PLUGIN_ID,GeLoadString(IDS_MY_SHADER),0, MyShader::Alloc,"myshader",0);
}
-ScottA