added Gradient.h
This commit is contained in:
144
inc/hgl/type/Gradient.h
Normal file
144
inc/hgl/type/Gradient.h
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/type/DataType.h>
|
||||||
|
#include<hgl/type/List.h>
|
||||||
|
#include<hgl/util/sort/Sort.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
template<typename P,typename T> struct GradientStop
|
||||||
|
{
|
||||||
|
P pos;
|
||||||
|
T data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
*/
|
||||||
|
template<typename P,typename T> class Gradient
|
||||||
|
{
|
||||||
|
using GS=GradientStop<P,T>;
|
||||||
|
|
||||||
|
List<GS> stop_list;
|
||||||
|
|
||||||
|
bool dirty;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void Sort()
|
||||||
|
{
|
||||||
|
if(!dirty||stop_list.GetCount()<2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Comparator<GS> comp;
|
||||||
|
|
||||||
|
hgl::Sort(stop_list,&comp);
|
||||||
|
|
||||||
|
dirty=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Gradient()
|
||||||
|
{
|
||||||
|
dirty=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(const P &pos,const T &data)
|
||||||
|
{
|
||||||
|
GS gs;
|
||||||
|
|
||||||
|
gs.pos=pos;
|
||||||
|
gs.data=data;
|
||||||
|
|
||||||
|
stop_list.Add(gs);
|
||||||
|
dirty=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
stop_list.Clear();
|
||||||
|
dirty=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool GetLowest(P &pos)const
|
||||||
|
{
|
||||||
|
GS gs;
|
||||||
|
|
||||||
|
if(stop_list.First(gs))
|
||||||
|
{
|
||||||
|
pos=gs.pos;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool GetHighest(P &pos)const
|
||||||
|
{
|
||||||
|
GS gs;
|
||||||
|
|
||||||
|
if(stop_list.Last(gs))
|
||||||
|
{
|
||||||
|
pos=gs.pos;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Get(T &reuslt,const T &start,const T &end,const float &pos)
|
||||||
|
{
|
||||||
|
result=start+(end-start)*pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void Get(T &result,const P &pos)
|
||||||
|
{
|
||||||
|
const uint count=stop_list.GetCount();
|
||||||
|
|
||||||
|
if(count<=0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sort();
|
||||||
|
|
||||||
|
GS *cp=stop_list.GetData();
|
||||||
|
GS *pp;
|
||||||
|
|
||||||
|
if(count<2||pos<=cp->pos)
|
||||||
|
{
|
||||||
|
result=cp->data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pos>=cp[count-1].pos)
|
||||||
|
{
|
||||||
|
result=cp[count-1].data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp=cp;
|
||||||
|
++cp;
|
||||||
|
for(uint i=1;i<count;i++)
|
||||||
|
{
|
||||||
|
if(pos<=cp->pos)
|
||||||
|
{
|
||||||
|
Get(result,pp->data,cp->data,float(pos-pp->pos)/float(cp->pos-pp->pos));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++pp;
|
||||||
|
++cp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};//class Gradient
|
||||||
|
|
||||||
|
#define HGL_GRADIENT_DEFINE(name,P,T) using name=Gradient<P,T>; \
|
||||||
|
using name##Stop=GradientStop<P,T>; \
|
||||||
|
\
|
||||||
|
int Comparator<name##Stop>::compare(const name##Stop &a,const name##Stop &b)const \
|
||||||
|
{ \
|
||||||
|
return a.pos-b.pos; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<> void name::Get(T &result,const T &start,const T &end,const float &pos)
|
||||||
|
}//namespace hgl
|
Reference in New Issue
Block a user