#include "BRAY_HdSphere.h"
using namespace UT::Literal;
using namespace HDK_Sample;
namespace
{
    
    static constexpr 
UT_StringLit       theDisplayColor(
"displayColor");
 
    
    static BRAY_HdSphere &
    getFactory()
    {
        static BRAY_HdSphere    theProc;
        return theProc;
    }
    
    class ParamListBuilder
    {
    public:
        ParamListBuilder()
        {
                {
                    theRadius.asHolder(),
                    1,
                    false
                },
                {
                    theColor.asHolder(),
                    3,
                    false
                },
            };
            myParms = UTmakeUnique<BRAY_AttribList>(
parms, SYSarraySize(parms), 
false);
 
        }
    };
    
    {
    public:
        CustomSphere()
            , myDisplayColor(0, 0, 0)
        {
                { theRadius.asHolder(),
                  1,
                  false,
                },
                { theColor.asHolder(),
                  3,
                  false
                },
                { theDisplayColor.asHolder(),
                  3,
                  false
                },
            };
            
            
            
            myDisplayColor = 0;
            uint    seed = SYSpointerHash(
this);
 
            while (myDisplayColor.maxComponent() < .7)
            {
                            SYSfastRandom(seed),
                            SYSfastRandom(seed));
            }
        }
        ~CustomSphere() override
        {
        }
        {
            return myAttribs;
        }
        {
            bounds.
initBounds(-myRadius, -myRadius, -myRadius);
 
        }
        HitPtr 
intersect(
const Ray32 &ray)
 const override 
        {
            return intersectSphere<fpreal32>(ray);
        }
        HitPtr 
intersect(
const Ray64 &ray)
 const override 
        {
            return intersectSphere<fpreal64>(ray);
        }
        {
            return myDisplayColor;
        }
        void doSetParameter(
        {
        }
        void doSetParameter(
                int n) override
        {
        }
        void doSetParameter(
                int n) override
        {
            if (key == theRadius.asRef())
            {
                
                myRadius = vals[0];
            }
            else if (key == theColor.asRef())
            {
                
                
                
                if (n == 1)
                else if (n >= 3)
                    myDisplayColor = 
UT_Vector3(vals[0], vals[1], vals[2]);
 
            }
        }
        void doSetParameter(
                int n) override
        {
        }
        void doSetParameter(
                int n) override
        {
        }
        void doBeginUpdate() override
        {
        }
        void doEndUpdate() override
        {
        }
        bool checkIsValid() const override { return true; }
        attribVal(
                int attrib,
                const Hit &hit_info,
        {
            return evalAttribute(attrib, time, hit_info, buf, size);
        }
        attribVal(
                int attrib,
                const Hit &hit_info,
                int size) const override
        {
            return evalAttribute(attrib, time, hit_info, buf, size);
        }
        attribVal(
                int attrib,
                const Hit &hit_info,
                int size) const override
        {
            
            switch (attrib)
            {
                case 0:
                    return &myRadius;
                case 1:
                case 2:
                    return myDisplayColor.data();
                default:
            }
        }
        attribVal(
                int attrib,
                const Hit &hit_info,
                int size) const override
        {
            
            
            switch (attrib)
            {
                case 0:
                    buf[0] = myRadius;
                case 1:
                case 2:
                    std::copy(myDisplayColor.data(), myDisplayColor.data()+3, 
buf);
 
                default:
            }
        }
        attribVal(
                int attrib,
                const Hit &hit_info,
                int size) const override
        {
            return evalAttribute(attrib, time, hit_info, buf, size);
        }
        template <typename T>
        evalAttribute(
                int attrib,
                const Hit &hit,
                int size) const
        {
        }
        {
        }
        {
        }
    protected:
        
        template <typename T> HitPtr
        intersectSphere(const Ray<T> &ray) const
        {
            
            T   b = 2 * 
dot(ray.org, ray.dir);
 
            T   c = ray.org.length2() - myRadius * myRadius;
 
            
            if (d < 0)
                return HitPtr();
            d = SYSsqrt(d);
            
            
            
            if (t0 > 0 && t0 < dist)
                dist = t0;
            else if (t1 > 0 && t1 < dist)
                dist = t1;
            else
                return HitPtr();
            
            HitPtr      hit = getHit();
            hit->Ng = ray.org + dist * ray.dir;
            hit->Ng.normalize();
            return hit;
        }
        private:
            float                         myRadius;
        };
    }
BRAY_HdSphere::BRAY_HdSphere()
{
}
BRAY_HdSphere::~BRAY_HdSphere()
{
}
BRAY_HdSphere::create() const
{
    return new CustomSphere;
}
BRAY_HdSphere::paramList() const
{
    
    static ParamListBuilder builder;
    return builder.myParms.get();
}
void
{
    getFactory();       
}