/*
Based on the shader code given in the Arnold doc "Creating a Shader".
    https://docs.arnoldrenderer.com/display/AFMUG/Creating+a+shader#CreatingaShader-1.1.1InstallingaC++Compiler 
Malcolm Kesson
Aug 17 2019
*/
#include <ai.h>
#include <cstring>
  
AtRGB mix(AtRGB c1, AtRGB c2, float alpha) {
    return c1 * (1.0 - alpha) + c2 * alpha;
    }
    
AI_SHADER_NODE_EXPORT_METHODS(SampleMethods);
 
namespace {
    enum paramIndex { k_numSides, k_innerRadius, k_lineThickness, k_baseColor, k_patternColor};
    };
 
node_parameters {
    AiParameterFlt("numSides", 5);
    AiParameterFlt("innerRadius", 0.25);
    AiParameterFlt("lineThickness", 0.02);
  
    AiParameterRGB("baseColor", 0.7f, 0.7f, 0);
    AiParameterRGB("patternColor", 0.7f, 0, 0);
    }
 
shader_evaluate {
    float numSides = AiShaderEvalParamFlt(k_numSides);
    float innerRadius = AiShaderEvalParamFlt(k_innerRadius);
    float lineThickness = AiShaderEvalParamFlt(k_lineThickness);
    AtRGB base = AiShaderEvalParamRGB(k_baseColor);
    AtRGB pat = AiShaderEvalParamRGB(k_patternColor);
    
    // 1   Convert the 'uv' to polar coordinates
    //     Note: positive theta is clockwise.
    float   theta = atan2(sg->v - 0.5, sg->u - 0.5); // -PI to PI radians
    if(theta < 0.0)
        theta += AI_PITIMES2;        //  0 to 2PI radians    
  
    // 2   Find the "segment" in which the current shading point is located.
    float interior = AI_PITIMES2/numSides;
    float segment = floor(theta/interior);    
    
    // 3   Find the angle to (counter) rotate the current shading point. 
    //     Note: positive rotation is anti-clockwise.
    float rotation = segment * interior + interior/2;
  
    // 4   Apply a 'Z' rotation
    float   x = sg->u - 0.5,
            y = 0.5 - sg->v;
    x = x * cos(rotation) - y * sin(rotation);
    
    // 5   Use the x value of the 'Z' rotation to determine the 
    //     "proximity" of the current shading point to a polygon edge.
    //     Using the smoothstep function twice ensures "proximity" is in 
    //     the range 0.0 to 1.0.
    float proximity = AiSmoothStep(innerRadius - lineThickness/2, innerRadius, x) *
                  (1.0 - AiSmoothStep(innerRadius, innerRadius + lineThickness/2, x));
      
    // 6   Finally, use "proximity" to output the appropriate color.       
    sg->out.RGB() =  mix(base, pat, proximity);
    }
 
node_loader {
    if (i > 0)
        return false; 
    node->methods        = SampleMethods;
    node->output_type    = AI_TYPE_RGB;
    node->name           = "mkPolygon";
    node->node_type      = AI_NODE_SHADER;
    strcpy(node->version, AI_VERSION);
    return true;
    }
    
// The remaining macros can be left "empty"
node_initialize {  
//    AiMsgSetConsoleFlags(AI_LOG_DEBUG); 
    }
node_update { }
node_finish { }