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