00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Renderer.h"
00018 #include "PolyPrimitive.h"
00019 #include "State.h"
00020
00021
00022
00023
00024 using namespace Fluxus;
00025
00026 PolyPrimitive::PolyPrimitive(Type t) :
00027 m_IndexMode(false),
00028 m_Type(t)
00029 {
00030 AddData("p",new TypedPData<dVector>);
00031 AddData("n",new TypedPData<dVector>);
00032 AddData("c",new TypedPData<dColour>);
00033 AddData("t",new TypedPData<dVector>);
00034
00035
00036 PDataDirty();
00037 }
00038
00039 PolyPrimitive::PolyPrimitive(const PolyPrimitive &other) :
00040 Primitive(other),
00041 m_IndexMode(other.m_IndexMode),
00042 m_IndexData(other.m_IndexData),
00043 m_Type(other.m_Type)
00044 {
00045 PDataDirty();
00046 }
00047
00048 PolyPrimitive::~PolyPrimitive()
00049 {
00050 }
00051
00052 PolyPrimitive *PolyPrimitive::Clone() const
00053 {
00054 return new PolyPrimitive(*this);
00055 }
00056
00057 void PolyPrimitive::Clear()
00058 {
00059 Resize(0);
00060 m_ConnectedVerts.clear();
00061 m_GeometricNormals.clear();
00062 m_UniqueEdges.clear();
00063 }
00064
00065 void PolyPrimitive::PDataDirty()
00066 {
00067
00068 m_VertData=GetDataVec<dVector>("p");
00069 m_NormData=GetDataVec<dVector>("n");
00070 m_ColData=GetDataVec<dColour>("c");
00071 m_TexData=GetDataVec<dVector>("t");
00072 }
00073
00074 void PolyPrimitive::AddVertex(const dVertex &Vert)
00075 {
00076 m_VertData->push_back(Vert.point);
00077 m_NormData->push_back(Vert.normal);
00078 m_ColData->push_back(Vert.col);
00079 m_TexData->push_back(dVector(Vert.s, Vert.t, 0));
00080
00081 m_ConnectedVerts.clear();
00082 m_GeometricNormals.clear();
00083 m_UniqueEdges.clear();
00084 }
00085
00086 void PolyPrimitive::Render()
00087 {
00088
00089 if (m_VertData->size()<3) return;
00090 if (m_IndexMode && m_IndexData.size()<3) return;
00091
00092 int type=0;
00093 switch (m_Type)
00094 {
00095 case TRISTRIP : type=GL_TRIANGLE_STRIP; break;
00096 case QUADS :
00097
00098 if (m_IndexMode)
00099 {
00100 if (m_IndexData.size()<4) return;
00101 }
00102 else
00103 {
00104 if (m_VertData->size()<4) return;
00105 }
00106 type=GL_QUADS;
00107 break;
00108 case TRILIST : type=GL_TRIANGLES; break;
00109 case TRIFAN : type=GL_TRIANGLE_FAN; break;
00110 case POLYGON : type=GL_POLYGON; break;
00111 }
00112
00113 if (m_State.Hints & HINT_AALIAS) glEnable(GL_LINE_SMOOTH);
00114 else glDisable(GL_LINE_SMOOTH);
00115
00116 if (m_State.Hints & HINT_NORMAL)
00117 {
00118 glColor3f(1,0,0);
00119 glDisable(GL_LIGHTING);
00120 glBegin(GL_LINES);
00121 for (unsigned int i=0; i<m_VertData->size(); i++)
00122 {
00123 glVertex3fv((*m_VertData)[i].arr());
00124 glVertex3fv(((*m_VertData)[i]+(*m_NormData)[i]).arr());
00125 }
00126 glEnd();
00127 glEnable(GL_LIGHTING);
00128 }
00129 if (m_State.Hints & HINT_UNLIT) glDisable(GL_LIGHTING);
00130
00131 glVertexPointer(3,GL_FLOAT,sizeof(dVector),(void*)m_VertData->begin()->arr());
00132 glNormalPointer(GL_FLOAT,sizeof(dVector),(void*)m_NormData->begin()->arr());
00133 glTexCoordPointer(3,GL_FLOAT,sizeof(dVector),(void*)m_TexData->begin()->arr());
00134
00135 if (m_State.Hints & HINT_MULTITEX)
00136 {
00137 for (int n=1; n<MAX_TEXTURES; n++)
00138 {
00139 char name[3];
00140 snprintf(name,3,"t%d",n);
00141 TypedPData<dVector> *tex = dynamic_cast<TypedPData<dVector>*>(GetDataRaw(name));
00142 if (tex!=NULL)
00143 {
00144 #ifdef ENABLE_MULTITEXTURE
00145 glClientActiveTexture(GL_TEXTURE0+n);
00146 #endif
00147 glTexCoordPointer(3,GL_FLOAT,sizeof(dVector),(void*)tex->m_Data.begin()->arr());
00148 }
00149 }
00150 #ifdef ENABLE_MULTITEXTURE
00151 glClientActiveTexture(GL_TEXTURE0);
00152 #endif
00153 }
00154
00155 if (m_State.Hints & HINT_VERTCOLS)
00156 {
00157 glEnableClientState(GL_COLOR_ARRAY);
00158 glColorPointer(3,GL_FLOAT,sizeof(dVector),(void*)m_ColData->begin()->arr());
00159 }
00160 else
00161 {
00162 glDisableClientState(GL_COLOR_ARRAY);
00163 }
00164
00165 if (m_State.Hints & HINT_SOLID)
00166 {
00167 if (m_IndexMode) glDrawElements(type,m_IndexData.size(),GL_UNSIGNED_INT,&(m_IndexData[0]));
00168 else glDrawArrays(type,0,m_VertData->size());
00169 }
00170
00171 if (m_State.Hints & HINT_WIRE)
00172 {
00173 glDisable(GL_TEXTURE_2D);
00174 glPolygonOffset(1,1);
00175 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00176 glColor4fv(m_State.WireColour.arr());
00177 glDisable(GL_LIGHTING);
00178 if (m_IndexMode) glDrawElements(type,m_IndexData.size(),GL_UNSIGNED_INT,&(m_IndexData[0]));
00179 else glDrawArrays(type,0,m_VertData->size());
00180 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
00181 glEnable(GL_LIGHTING);
00182 glEnable(GL_TEXTURE_2D);
00183 }
00184
00185 if (m_State.Hints & HINT_POINTS)
00186 {
00187 glDisable(GL_TEXTURE_2D);
00188 glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
00189 glColor4fv(m_State.WireColour.arr());
00190 glDisable(GL_LIGHTING);
00191 if (m_IndexMode) glDrawElements(type,m_IndexData.size(),GL_UNSIGNED_INT,&(m_IndexData[0]));
00192 else glDrawArrays(type,0,m_VertData->size());
00193 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
00194 glEnable(GL_LIGHTING);
00195 glEnable(GL_TEXTURE_2D);
00196 }
00197
00198
00199 if (m_State.Hints & HINT_UNLIT) glEnable(GL_LIGHTING);
00200 }
00201
00202 void PolyPrimitive::RecalculateNormals(bool smooth)
00203 {
00204 GenerateTopology();
00205 CalculateGeometricNormals();
00206
00207 if (!m_GeometricNormals.empty())
00208 {
00209 if (m_IndexMode)
00210 {
00211 vector<int> count(m_VertData->size());
00212
00213
00214 for (unsigned int i=0; i<m_NormData->size(); i++)
00215 {
00216 (*m_NormData)[i]=dVector(0,0,0);
00217 count[i]=0;
00218 }
00219
00220
00221 for (unsigned int i=0; i<m_IndexData.size(); i++)
00222 {
00223 (*m_NormData)[m_IndexData[i]]+=m_GeometricNormals[i];
00224 count[m_IndexData[i]]++;
00225 }
00226
00227
00228 for (unsigned int i=0; i<m_NormData->size(); i++)
00229 {
00230 (*m_NormData)[i]/=(float)count[i];
00231 }
00232 }
00233 else
00234 {
00235 for (unsigned int i=0; i<m_VertData->size(); i++)
00236 {
00237 (*m_NormData)[i]=m_GeometricNormals[i];
00238 }
00239
00240 if (smooth)
00241 {
00242
00243 TypedPData<dVector> *newnorms = new TypedPData<dVector>;
00244 for (unsigned int i=0; i<m_VertData->size(); i++)
00245 {
00246 float count=1;
00247 dVector n = (*m_NormData)[i];
00248 for (vector<int>::iterator b=m_ConnectedVerts[i].begin();
00249 b!=m_ConnectedVerts[i].end(); b++)
00250 {
00251 n+=(*m_NormData)[*b];
00252 count+=1;
00253 }
00254 newnorms->m_Data.push_back((n/count).normalise());
00255 }
00256 SetDataRaw("n", newnorms);
00257 }
00258 }
00259 }
00260 }
00261
00262 void PolyPrimitive::ConvertToIndexed()
00263 {
00264 if (m_ConnectedVerts.empty())
00265 {
00266 CalculateConnected();
00267 }
00268
00269 TypedPData<dVector> *NewVerts = new TypedPData<dVector>;
00270 TypedPData<dVector> *NewNorms = new TypedPData<dVector>;
00271 TypedPData<dColour> *NewCols = new TypedPData<dColour>;
00272 TypedPData<dVector> *NewTex = new TypedPData<dVector>;
00273
00274 m_IndexData.clear();
00275 int vert=0;
00276 int index=0;
00277 map<int,int> verttoindex;
00278 for (vector<vector<int> >::iterator i=m_ConnectedVerts.begin();
00279 i!=m_ConnectedVerts.end(); i++)
00280 {
00281 if (!i->empty() && verttoindex.find(vert)==verttoindex.end())
00282 {
00283
00284
00285 NewVerts->m_Data.push_back((*m_VertData)[(*i)[0]]);
00286 NewNorms->m_Data.push_back((*m_NormData)[(*i)[0]]);
00287 NewCols->m_Data.push_back((*m_ColData)[(*i)[0]]);
00288 NewTex->m_Data.push_back((*m_TexData)[(*i)[0]]);
00289 m_IndexData.push_back(index);
00290
00291
00292 for (vector<int>::iterator v=i->begin(); v!=i->end(); v++)
00293 {
00294 verttoindex[*v]=index;
00295 }
00296
00297 index++;
00298 }
00299 else
00300 {
00301 m_IndexData.push_back(verttoindex[vert]);
00302 }
00303
00304 vert++;
00305 }
00306
00307 SetDataRaw("p", NewVerts);
00308 SetDataRaw("n", NewNorms);
00309 SetDataRaw("c", NewCols);
00310 SetDataRaw("t", NewTex);
00311
00312 m_IndexMode=true;
00313 }
00314
00315 void PolyPrimitive::GenerateTopology()
00316 {
00317 if (m_ConnectedVerts.empty())
00318 {
00319 CalculateConnected();
00320 }
00321
00322 if (m_GeometricNormals.empty())
00323 {
00324 CalculateGeometricNormals();
00325 }
00326 }
00327
00328 void PolyPrimitive::CalculateConnected()
00329 {
00330
00331 if (m_IndexMode)
00332 {
00333 for (unsigned int i=0; i<m_IndexData.size(); i++)
00334 {
00335 vector<int> connected;
00336 for (unsigned int b=0; b<m_IndexData.size(); b++)
00337 {
00338
00339 if (i!=b && m_IndexData[i]==m_IndexData[b])
00340 {
00341 connected.push_back(b);
00342 }
00343 }
00344 m_ConnectedVerts.push_back(connected);
00345 }
00346 }
00347 else
00348 {
00349 for (unsigned int i=0; i<m_VertData->size(); i++)
00350 {
00351 vector<int> connected;
00352 for (unsigned int b=0; b<m_VertData->size(); b++)
00353 {
00354
00355 if (i!=b && (*m_VertData)[i].feq((*m_VertData)[b]))
00356 {
00357 connected.push_back(b);
00358 }
00359 }
00360 m_ConnectedVerts.push_back(connected);
00361 }
00362 }
00363 }
00364
00365
00366 void PolyPrimitive::CalculateGeometricNormals()
00367 {
00369
00370 if (m_Type==POLYGON && m_VertData->size()>2)
00371 {
00372 m_GeometricNormals.clear();
00373 dVector a((*m_VertData)[0]-(*m_VertData)[1]);
00374 dVector b((*m_VertData)[1]-(*m_VertData)[2]);
00375 dVector normal(a.cross(b));
00376 normal.normalise();
00377
00378 for (unsigned int i=0; i<m_VertData->size(); i++)
00379 {
00380 m_GeometricNormals.push_back(normal);
00381 }
00382
00383 return;
00384 }
00385
00386 int stride=0;
00387 if (m_Type==TRISTRIP) stride=2;
00388 if (m_Type==QUADS) stride=4;
00389 if (m_Type==TRILIST) stride=3;
00390 if (stride>0)
00391 {
00392 m_GeometricNormals.clear();
00393
00394 if (m_IndexMode)
00395 {
00396 for (unsigned int i=0; i<m_IndexData.size(); i+=stride)
00397 {
00398 if (i+2<m_IndexData.size())
00399 {
00400 dVector a((*m_VertData)[m_IndexData[i]]-(*m_VertData)[m_IndexData[i+1]]);
00401 dVector b((*m_VertData)[m_IndexData[i+1]]-(*m_VertData)[m_IndexData[i+2]]);
00402 dVector normal(a.cross(b));
00403 normal.normalise();
00404 for (int n=0; n<stride; n++)
00405 {
00406 m_GeometricNormals.push_back(normal);
00407 }
00408 }
00409 }
00410 }
00411 else
00412 {
00413 for (unsigned int i=0; i<m_VertData->size(); i+=stride)
00414 {
00415 if (i+2<m_VertData->size())
00416 {
00417 dVector a((*m_VertData)[i]-(*m_VertData)[i+1]);
00418 dVector b((*m_VertData)[i+1]-(*m_VertData)[i+2]);
00419 dVector normal(a.cross(b));
00420 normal.normalise();
00421 for (int n=0; n<stride; n++)
00422 {
00423 m_GeometricNormals.push_back(normal);
00424 }
00425 }
00426 }
00427 }
00428 }
00429 }
00430
00431 void PolyPrimitive::CalculateUniqueEdges()
00432 {
00433 if (m_UniqueEdges.empty())
00434 {
00435
00436 int stride=0;
00437 if (m_Type==TRISTRIP) stride=2;
00438 if (m_Type==QUADS) stride=4;
00439 if (m_Type==TRILIST) stride=3;
00440 if (stride>0)
00441 {
00442 set<pair<int,int> > firstpass;
00443
00444 unsigned int vertcount=m_VertData->size();
00445 if (m_IndexMode) vertcount=m_IndexData.size();
00446
00447
00448 for (unsigned int i=0; i<vertcount; i+=stride)
00449 {
00450 for (int n=0; n<stride-1; n++)
00451 {
00452 firstpass.insert(pair<int,int>(n+i,n+i+1));
00453 }
00454 firstpass.insert(pair<int,int>(i+stride-1,i));
00455 }
00456
00457 set<pair<int,int> > stored;
00458 pair<int,int> key;
00459
00460
00461 for (unsigned int i=0; i<vertcount; i+=stride)
00462 {
00463 for (int n=0; n<stride-1; n++)
00464 {
00465 UniqueEdgesFindShared(pair<int,int>(n+i,n+i+1), firstpass, stored);
00466 }
00467 UniqueEdgesFindShared(pair<int,int>(i+stride-1,i), firstpass, stored);
00468 }
00469 }
00470 }
00471 }
00472
00473 void PolyPrimitive::UniqueEdgesFindShared(pair<int,int> edge, set<pair<int,int> > firstpass, set<pair<int,int> > &stored)
00474 {
00475 vector<pair<int,int> > edges;
00476
00477 if (stored.find(edge)==stored.end() && stored.find(pair<int,int>(edge.second,edge.first))==stored.end())
00478 {
00479
00480 edges.push_back(edge);
00481 stored.insert(edge);
00482
00483
00484
00485
00486 for (vector<int>::iterator a=m_ConnectedVerts[edge.first].begin();
00487 a!=m_ConnectedVerts[edge.first].end(); a++)
00488 {
00489 for (vector<int>::iterator b=m_ConnectedVerts[edge.second].begin();
00490 b!=m_ConnectedVerts[edge.second].end(); b++)
00491 {
00492
00493 pair<int, int> candidate(*a,*b);
00494 if (firstpass.find(candidate)!=firstpass.end() &&
00495 stored.find(candidate)==stored.end() )
00496 {
00497 edges.push_back(candidate);
00498 stored.insert(candidate);
00499
00500 }
00501
00502 pair<int, int> rcandidate(*b,*a);
00503 if (firstpass.find(rcandidate)!=firstpass.end() &&
00504 stored.find(rcandidate)==stored.end() )
00505 {
00506 edges.push_back(rcandidate);
00507 stored.insert(rcandidate);
00508
00509 }
00510 }
00511 }
00512
00513 if (!edges.empty())
00514 {
00515 m_UniqueEdges.push_back(edges);
00516 }
00517 }
00518 }
00519
00520 dBoundingBox PolyPrimitive::GetBoundingBox()
00521 {
00522 dBoundingBox box;
00523 for (vector<dVector>::iterator i=m_VertData->begin(); i!=m_VertData->end(); ++i)
00524 {
00525 box.expand(*i);
00526 }
00527 return box;
00528 }
00529
00530 void PolyPrimitive::ApplyTransform(bool ScaleRotOnly)
00531 {
00532 if (!ScaleRotOnly)
00533 {
00534 for (vector<dVector>::iterator i=m_VertData->begin(); i!=m_VertData->end(); ++i)
00535 {
00536 *i=GetState()->Transform.transform(*i);
00537
00538 }
00539 }
00540 else
00541 {
00542 for (unsigned int i=0; i<m_VertData->size(); i++)
00543 {
00544 (*m_VertData)[i]=GetState()->Transform.transform_no_trans((*m_VertData)[i]);
00545 (*m_NormData)[i]=GetState()->Transform.transform_no_trans((*m_NormData)[i]).normalise();
00546 }
00547 }
00548
00549 GetState()->Transform.init();
00550 }
00551