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
00241 if (smooth)
00242 {
00243
00244 TypedPData<dVector> *newnorms = new TypedPData<dVector>;
00245 for (unsigned int i=0; i<m_VertData->size(); i++)
00246 {
00247 float count=1;
00248 dVector n = (*m_NormData)[i];
00249 for (vector<int>::iterator b=m_ConnectedVerts[i].begin();
00250 b!=m_ConnectedVerts[i].end(); b++)
00251 {
00252 n+=(*m_NormData)[*b];
00253 count+=1;
00254 }
00255 newnorms->m_Data.push_back((n/count).normalise());
00256 }
00257 SetDataRaw("n", newnorms);
00258 }
00259 }
00260 }
00261
00262 void PolyPrimitive::ConvertToIndexed()
00263 {
00264 if (m_IndexMode) return;
00265
00266 if (m_ConnectedVerts.empty())
00267 {
00268 CalculateConnected();
00269 }
00270
00271 TypedPData<dVector> *NewVerts = new TypedPData<dVector>;
00272 TypedPData<dVector> *NewNorms = new TypedPData<dVector>;
00273 TypedPData<dColour> *NewCols = new TypedPData<dColour>;
00274 TypedPData<dVector> *NewTex = new TypedPData<dVector>;
00275
00276 m_IndexData.clear();
00277 int vert=0;
00278 int index=0;
00279 map<int,int> verttoindex;
00280 for (vector<vector<int> >::iterator i=m_ConnectedVerts.begin();
00281 i!=m_ConnectedVerts.end(); i++)
00282 {
00283 if (!i->empty() && verttoindex.find(vert)==verttoindex.end())
00284 {
00285
00286
00287 NewVerts->m_Data.push_back((*m_VertData)[(*i)[0]]);
00288 NewNorms->m_Data.push_back((*m_NormData)[(*i)[0]]);
00289 NewCols->m_Data.push_back((*m_ColData)[(*i)[0]]);
00290 NewTex->m_Data.push_back((*m_TexData)[(*i)[0]]);
00291 m_IndexData.push_back(index);
00292
00293
00294 for (vector<int>::iterator v=i->begin(); v!=i->end(); v++)
00295 {
00296 verttoindex[*v]=index;
00297 }
00298
00299 index++;
00300 }
00301 else
00302 {
00303 m_IndexData.push_back(verttoindex[vert]);
00304 }
00305
00306 vert++;
00307 }
00308
00309 SetDataRaw("p", NewVerts);
00310 SetDataRaw("n", NewNorms);
00311 SetDataRaw("c", NewCols);
00312 SetDataRaw("t", NewTex);
00313
00314 m_IndexMode=true;
00315 }
00316
00317 void PolyPrimitive::GenerateTopology()
00318 {
00319 if (m_ConnectedVerts.empty())
00320 {
00321 CalculateConnected();
00322 }
00323
00324 if (m_GeometricNormals.empty())
00325 {
00326 CalculateGeometricNormals();
00327 }
00328 }
00329
00330 void PolyPrimitive::CalculateConnected()
00331 {
00332
00333 if (m_IndexMode)
00334 {
00335 for (unsigned int i=0; i<m_IndexData.size(); i++)
00336 {
00337 vector<int> connected;
00338 for (unsigned int b=0; b<m_IndexData.size(); b++)
00339 {
00340
00341 if (i!=b && (m_IndexData[i]==m_IndexData[b] ||
00342
00343 ((*m_VertData)[m_IndexData[i]].feq((*m_VertData)[m_IndexData[b]]))))
00344 {
00345 connected.push_back(b);
00346 }
00347 }
00348
00349 m_ConnectedVerts.push_back(connected);
00350 }
00351 }
00352 else
00353 {
00354
00355 for (unsigned int i=0; i<m_VertData->size(); i++)
00356 {
00357 vector<int> connected;
00358 for (unsigned int b=0; b<m_VertData->size(); b++)
00359 {
00360
00361 if (i!=b && (*m_VertData)[i].feq((*m_VertData)[b]))
00362 {
00363 connected.push_back(b);
00364 }
00365 }
00366
00367 m_ConnectedVerts.push_back(connected);
00368 }
00369 }
00370 }
00371
00372
00373 void PolyPrimitive::CalculateGeometricNormals()
00374 {
00376
00377 if (m_Type==POLYGON && m_VertData->size()>2)
00378 {
00379 m_GeometricNormals.clear();
00380 dVector a((*m_VertData)[0]-(*m_VertData)[1]);
00381 dVector b((*m_VertData)[1]-(*m_VertData)[2]);
00382 dVector normal(a.cross(b));
00383 normal.normalise();
00384
00385 for (unsigned int i=0; i<m_VertData->size(); i++)
00386 {
00387 m_GeometricNormals.push_back(normal);
00388 }
00389
00390 return;
00391 }
00392
00393 int stride=0;
00394 if (m_Type==TRISTRIP) stride=2;
00395 if (m_Type==QUADS) stride=4;
00396 if (m_Type==TRILIST) stride=3;
00397 if (stride>0)
00398 {
00399 m_GeometricNormals.clear();
00400
00401 if (m_IndexMode)
00402 {
00403 for (unsigned int i=0; i<m_IndexData.size(); i+=stride)
00404 {
00405 if (i+2<m_IndexData.size())
00406 {
00407 dVector a((*m_VertData)[m_IndexData[i]]-(*m_VertData)[m_IndexData[i+1]]);
00408 dVector b((*m_VertData)[m_IndexData[i+1]]-(*m_VertData)[m_IndexData[i+2]]);
00409 dVector normal(a.cross(b));
00410 normal.normalise();
00411 for (int n=0; n<stride; n++)
00412 {
00413 m_GeometricNormals.push_back(normal);
00414 }
00415 }
00416 }
00417 }
00418 else
00419 {
00420 for (unsigned int i=0; i<m_VertData->size(); i+=stride)
00421 {
00422 if (i+2<m_VertData->size())
00423 {
00424 dVector a((*m_VertData)[i]-(*m_VertData)[i+1]);
00425 dVector b((*m_VertData)[i+1]-(*m_VertData)[i+2]);
00426 dVector normal(a.cross(b));
00427 normal.normalise();
00428 for (int n=0; n<stride; n++)
00429 {
00430 m_GeometricNormals.push_back(normal);
00431 }
00432 }
00433 }
00434 }
00435 }
00436 }
00437
00438 void PolyPrimitive::CalculateUniqueEdges()
00439 {
00440 if (m_UniqueEdges.empty())
00441 {
00442
00443 int stride=0;
00444 if (m_Type==TRISTRIP) stride=2;
00445 if (m_Type==QUADS) stride=4;
00446 if (m_Type==TRILIST) stride=3;
00447 if (stride>0)
00448 {
00449 set<pair<int,int> > firstpass;
00450
00451 unsigned int vertcount=m_VertData->size();
00452 if (m_IndexMode) vertcount=m_IndexData.size();
00453
00454
00455 for (unsigned int i=0; i<vertcount; i+=stride)
00456 {
00457 for (int n=0; n<stride-1; n++)
00458 {
00459 firstpass.insert(pair<int,int>(n+i,n+i+1));
00460 }
00461 firstpass.insert(pair<int,int>(i+stride-1,i));
00462 }
00463
00464 set<pair<int,int> > stored;
00465 pair<int,int> key;
00466
00467
00468 for (unsigned int i=0; i<vertcount; i+=stride)
00469 {
00470 for (int n=0; n<stride-1; n++)
00471 {
00472 UniqueEdgesFindShared(pair<int,int>(n+i,n+i+1), firstpass, stored);
00473 }
00474 UniqueEdgesFindShared(pair<int,int>(i+stride-1,i), firstpass, stored);
00475 }
00476 }
00477 }
00478 }
00479
00480 void PolyPrimitive::UniqueEdgesFindShared(pair<int,int> edge, set<pair<int,int> > firstpass, set<pair<int,int> > &stored)
00481 {
00482 vector<pair<int,int> > edges;
00483
00484 if (stored.find(edge)==stored.end() && stored.find(pair<int,int>(edge.second,edge.first))==stored.end())
00485 {
00486
00487 edges.push_back(edge);
00488 stored.insert(edge);
00489
00490
00491
00492
00493 for (vector<int>::iterator a=m_ConnectedVerts[edge.first].begin();
00494 a!=m_ConnectedVerts[edge.first].end(); a++)
00495 {
00496 for (vector<int>::iterator b=m_ConnectedVerts[edge.second].begin();
00497 b!=m_ConnectedVerts[edge.second].end(); b++)
00498 {
00499
00500 pair<int, int> candidate(*a,*b);
00501 if (firstpass.find(candidate)!=firstpass.end() &&
00502 stored.find(candidate)==stored.end() )
00503 {
00504 edges.push_back(candidate);
00505 stored.insert(candidate);
00506
00507 }
00508
00509 pair<int, int> rcandidate(*b,*a);
00510 if (firstpass.find(rcandidate)!=firstpass.end() &&
00511 stored.find(rcandidate)==stored.end() )
00512 {
00513 edges.push_back(rcandidate);
00514 stored.insert(rcandidate);
00515
00516 }
00517 }
00518 }
00519
00520 if (!edges.empty())
00521 {
00522 m_UniqueEdges.push_back(edges);
00523 }
00524 }
00525 }
00526
00527 dBoundingBox PolyPrimitive::GetBoundingBox()
00528 {
00529 dBoundingBox box;
00530 for (vector<dVector>::iterator i=m_VertData->begin(); i!=m_VertData->end(); ++i)
00531 {
00532 box.expand(*i);
00533 }
00534 return box;
00535 }
00536
00537 void PolyPrimitive::ApplyTransform(bool ScaleRotOnly)
00538 {
00539 if (!ScaleRotOnly)
00540 {
00541 for (vector<dVector>::iterator i=m_VertData->begin(); i!=m_VertData->end(); ++i)
00542 {
00543 *i=GetState()->Transform.transform(*i);
00544
00545 }
00546 }
00547 else
00548 {
00549 for (unsigned int i=0; i<m_VertData->size(); i++)
00550 {
00551 (*m_VertData)[i]=GetState()->Transform.transform_no_trans((*m_VertData)[i]);
00552 (*m_NormData)[i]=GetState()->Transform.transform_no_trans((*m_NormData)[i]).normalise();
00553 }
00554 }
00555
00556 GetState()->Transform.init();
00557 }
00558