
// CPUStrokeTessellatorCtrlMain.cpp - CPU-centric "main" code for control shader implementation of polar stroking geometry

#include <math.h>

#include "countof.h"

#include "CPUStrokeTessellator.hpp"

#include <Cg/mul.hpp>

#include "../common/CommonStrokeTessellatorControlPrivate.hpp"

bool use_native_atan2 = false;

void CPUStrokeTessellator::setupLinkControlPoints(const float3 vin[6], const GLuint ndx[6])
{
    // For each of the vertexes in a link...
    for (int i=0; i<icountof(v); i++) {
        // Logically, this is the vertex (control point) shader:
        vertex_id[i] = ndx[i];  // Save vertex ID.
        v_orig[i] = vin[i];
        hpos[i] = mul(modelview_projection, vin[i]);
        if (stroke_space == WINDOW_SPACE) {
            v[i] = hpos[i] * float3(viewport_scale.xy,1);
        } else {
            v[i] = vin[i];
        }
    }

    for (int i=0; i<4; i++) {
        cp[i] = v[i];
    }
}

void CPUStrokeTessellator::setupLink(const float3 vin[6], const GLuint ndx[6])
{
    setupLinkControlPoints(vin, ndx);

    // This is where GLSL would launch the "main" tessellation control shader function.
    linkControlShader();
}

bool CPUStrokeTessellator::LinkTypeIsCurved() const
{
    return LinkTypeIsCurved(stashed_link_type);
}

bool CPUStrokeTessellator::LinkTypeIsQuadratic() const
{
    return (stashed_link_type == LT_QUADRATIC_SEGMENT);
}

void CPUStrokeTessellator::GetQuadraticControlPoints(float3 cps[3]) const
{
    cps[0] = cp[0];
    cps[1] = cp[1];
    cps[2] = cp[3];
}

void CPUStrokeTessellator::GetCubicControlPoints(float3 cps[4]) const
{
    cps[0] = cp[0];
    cps[1] = cp[1];
    cps[2] = cp[2];
    cps[3] = cp[3];
}

void CPUStrokeTessellator::GetCubicControlPoints(double3 cps[4]) const
{
    cps[0] = double3(cp[0]);
    cps[1] = double3(cp[1]);
    cps[2] = double3(cp[2]);
    cps[3] = double3(cp[3]);
}
