00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Renderer.h"
00018 #include "NURBSPrimitive.h"
00019 #include "State.h"
00020
00021 using namespace Fluxus;
00022
00023 NURBSPrimitive::NURBSPrimitive() :
00024 m_UOrder(0),
00025 m_VOrder(0),
00026 m_UCVCount(0),
00027 m_VCVCount(0),
00028 m_Stride(sizeof(dVector)/sizeof(float))
00029 {
00030 AddData("p",new TypedPData<dVector>);
00031 AddData("t",new TypedPData<dVector>);
00032 AddData("n",new TypedPData<dVector>);
00033
00034
00035 PDataDirty();
00036
00037 SetupSurface();
00038 }
00039
00040 NURBSPrimitive::NURBSPrimitive(const NURBSPrimitive &other) :
00041 Primitive(other),
00042 m_UKnotVec(other.m_UKnotVec),
00043 m_VKnotVec(other.m_VKnotVec),
00044 m_UOrder(other.m_UOrder),
00045 m_VOrder(other.m_VOrder),
00046 m_UCVCount(other.m_UCVCount),
00047 m_VCVCount(other.m_VCVCount),
00048 m_Stride(other.m_Stride)
00049 {
00050 SetupSurface();
00051 PDataDirty();
00052 }
00053
00054 NURBSPrimitive::~NURBSPrimitive()
00055 {
00056 gluDeleteNurbsRenderer(m_Surface);
00057 }
00058
00059 NURBSPrimitive* NURBSPrimitive::Clone() const
00060 {
00061 return new NURBSPrimitive(*this);
00062 }
00063
00064 void NURBSPrimitive::PDataDirty()
00065 {
00066
00067 m_CVVec=GetDataVec<dVector>("p");
00068 m_STVec=GetDataVec<dVector>("t");
00069 m_NVec=GetDataVec<dVector>("n");
00070 }
00071
00072 void NURBSPrimitive::SetupSurface()
00073 {
00074 m_Surface = gluNewNurbsRenderer();
00075
00076
00077 gluNurbsProperty(m_Surface, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);
00078 gluNurbsProperty(m_Surface, GLU_U_STEP, 20);
00079 gluNurbsProperty(m_Surface, GLU_DISPLAY_MODE, GLU_FILL);
00080 gluNurbsProperty(m_Surface, GLU_CULLING, GLU_TRUE);
00081 }
00082
00083 void NURBSPrimitive::Render()
00084 {
00085 if (m_State.Hints & HINT_UNLIT) glDisable(GL_LIGHTING);
00086
00087 if (m_State.Hints & HINT_AALIAS) glEnable(GL_LINE_SMOOTH);
00088 else glDisable(GL_LINE_SMOOTH);
00089
00090 if (m_State.Hints & HINT_SOLID)
00091 {
00092 gluNurbsProperty(m_Surface, GLU_DISPLAY_MODE, GLU_FILL);
00093
00094 gluBeginSurface(m_Surface);
00095
00096 if (!m_STVec->empty())
00097 {
00098 gluNurbsSurface(m_Surface,m_UKnotVec.size(),&(*m_UKnotVec.begin()),m_VKnotVec.size(),&(*m_VKnotVec.begin()),
00099 m_VCVCount*m_Stride,m_Stride,
00100 m_STVec->begin()->arr(),m_UOrder,m_VOrder,GL_MAP2_TEXTURE_COORD_2);
00101 }
00102
00103 if (!m_NVec->empty())
00104 {
00105 gluNurbsSurface(m_Surface,m_UKnotVec.size(),&(*m_UKnotVec.begin()),m_VKnotVec.size(),&(*m_VKnotVec.begin()),
00106 m_VCVCount*m_Stride,m_Stride,
00107 m_NVec->begin()->arr(),m_UOrder,m_VOrder,GL_MAP2_NORMAL);
00108 }
00109
00110 gluNurbsSurface(m_Surface,m_UKnotVec.size(),&(*m_UKnotVec.begin()),m_VKnotVec.size(),&(*m_VKnotVec.begin()),
00111 m_VCVCount*m_Stride,m_Stride,
00112 m_CVVec->begin()->arr(),m_UOrder,m_VOrder,GL_MAP2_VERTEX_3);
00113
00114 gluEndSurface(m_Surface);
00115 }
00116
00117 if (m_State.Hints & HINT_WIRE)
00118 {
00119 glDisable(GL_LIGHTING);
00120 glColor4fv(m_State.WireColour.arr());
00121 gluNurbsProperty(m_Surface, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
00122
00123 gluBeginSurface(m_Surface);
00124 gluNurbsSurface(m_Surface,m_UKnotVec.size(),&(*m_UKnotVec.begin()),m_VKnotVec.size(),&(*m_VKnotVec.begin()),
00125 m_VCVCount*m_Stride,m_Stride,
00126 m_CVVec->begin()->arr(),m_UOrder,m_VOrder,GL_MAP2_VERTEX_3);
00127
00128 gluEndSurface(m_Surface);
00129 glEnable(GL_LIGHTING);
00130 }
00131
00132 if (m_State.Hints & HINT_POINTS)
00133 {
00134 glColor3f(0,0,1);
00135 glDisable(GL_LIGHTING);
00136 glBegin(GL_POINTS);
00137 for (unsigned int n=0; n<m_CVVec->size(); n++)
00138 {
00139 glVertex3fv((*m_CVVec)[n].arr());
00140 }
00141 glEnd();
00142 glEnable(GL_LIGHTING);
00143 }
00144
00145 if (m_State.Hints & HINT_NORMAL)
00146 {
00147 glColor3f(1,0,0);
00148 glDisable(GL_LIGHTING);
00149 glBegin(GL_LINES);
00150 for (unsigned int i=0; i!=m_CVVec->size(); i++)
00151 {
00152 glVertex3fv((*m_CVVec)[i].arr());
00153 glVertex3fv(((*m_CVVec)[i]+(*m_NVec)[i]).arr());
00154 }
00155 glEnd();
00156 glEnable(GL_LIGHTING);
00157 }
00158
00159 if (m_State.Hints & HINT_UNLIT) glEnable(GL_LIGHTING);
00160
00161 }
00162
00163 void NURBSPrimitive::RecalculateNormals(bool smooth)
00164 {
00165 for (int n=0; n<(int)m_NVec->size(); n++)
00166 {
00167 int u=n-1;
00168 bool flip=false;
00169 if (n%m_VCVCount==0)
00170 {
00171 u=n+1;
00172 flip=true;
00173 }
00174
00175 int v=n-m_VCVCount;
00176
00177 if (n<m_VCVCount)
00178 {
00179 v=n+m_VCVCount;
00180 flip=true;
00181 }
00182
00183 dVector a=(*m_CVVec)[n]-(*m_CVVec)[u];
00184 dVector b=(*m_CVVec)[v]-(*m_CVVec)[n];
00185
00186 a.normalise();
00187 b.normalise();
00188 (*m_NVec)[n]=a.cross(b);
00189 (*m_NVec)[n].normalise();
00190
00191 if (flip)
00192 {
00193 (*m_NVec)[n]=-(*m_NVec)[n];
00194 }
00195
00196 }
00197 }
00198
00199 dBoundingBox NURBSPrimitive::GetBoundingBox()
00200 {
00201 dBoundingBox box;
00202 for (vector<dVector>::iterator i=m_CVVec->begin(); i!=m_CVVec->end(); ++i)
00203 {
00204 box.expand(*i);
00205 }
00206 return box;
00207 }
00208
00209 void NURBSPrimitive::ApplyTransform(bool ScaleRotOnly)
00210 {
00211 if (!ScaleRotOnly)
00212 {
00213 for (vector<dVector>::iterator i=m_CVVec->begin(); i!=m_CVVec->end(); ++i)
00214 {
00215 *i=GetState()->Transform.transform(*i);
00216 }
00217 }
00218 else
00219 {
00220 for (vector<dVector>::iterator i=m_CVVec->begin(); i!=m_CVVec->end(); ++i)
00221 {
00222 *i=GetState()->Transform.transform_no_trans(*i);
00223 }
00224 }
00225
00226 GetState()->Transform.init();
00227 }