2 FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
3 Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
33 #define DEGtoRAD (3.141592/180.0)
35 bool Mesh::mbInitStatic = false;
36 int Mesh::miBufSize[MAX_MFORMAT][MAX_BFORMAT];
40 debug.SendToConsole ( true );
42 m_Mform = MFormat::UDef;
49 Mesh& Mesh::operator= ( Mesh& src )
52 CopyAttributes ( src );
53 m_Mform = src.GetMeshBufs ( m_Vbuf, m_Ebuf, m_Fbuf );
57 void Mesh::InitStatic ()
60 miBufSize[ (int) FVF ][ (int) BVert ] = sizeof ( VertFVF );
61 miBufSize[ (int) FVF ][ (int) BFace ] = sizeof ( FaceFVF );
62 miBufSize[ (int) FVF ][ (int) BEdge ] = 0;
63 miBufSize[ (int) CM ][ (int) BVert ] = sizeof ( VertCM );
64 miBufSize[ (int) CM ][ (int) BEdge ] = sizeof ( EdgeCM );
65 miBufSize[ (int) CM ][ (int) BFace ] = sizeof ( FaceCM );
69 /*void Mesh::onUpdate ( objData dat, mint::Event* e )
83 m_Mform = (MFormat) e->getUChar ();
84 m_Vbuf = e->getUChar ();
85 m_Ebuf = e->getUChar ();
86 m_Fbuf = e->getUChar ();
87 num_buf = e->getInt ();
88 for (int b=0; b < num_buf; b++) {
89 dtype = e->getUChar ();
90 stride = e->getUShort ();
93 AddBuffer ( dtype, stride, max );
94 e->getMem ( mBuf[b].data, num * mBuf[b].stride );
98 mHeapNum = e->getInt ();
99 mHeapMax = e->getInt ();
100 mHeapFree = e->getInt ();
101 mHeap = new hval[mHeapMax];
102 e->getMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
107 void Mesh::UpdateMesh ()
109 int s = GetSize () + (mBuf.size()+1)*4*sizeof(int);
110 mint::Event* e = updateStart ( 'full', s );
112 e->attachUChar ( (char) m_Mform ) ;
113 e->attachUChar ( (char) m_Vbuf );
114 e->attachUChar ( (char) m_Ebuf );
115 e->attachUChar ( (char) m_Fbuf );
116 e->attachInt ( mBuf.size() );
117 for (int b=0; b < mBuf.size(); b++) {
118 e->attachUChar ( mBuf[b].dtype );
119 e->attachUShort ( mBuf[b].stride );
120 e->attachInt ( mBuf[b].num );
121 e->attachInt ( mBuf[b].max );
122 e->attachMem ( mBuf[b].data, mBuf[b].num * mBuf[b].stride );
124 e->attachInt ( mHeapNum );
125 e->attachInt ( mHeapMax );
126 e->attachInt ( mHeapFree );
127 e->attachMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
133 //------------------------------------------------------------------ FVF - Face-vertex-face Mesh
134 void Mesh::CreateFVF ()
136 if ( !mbInitStatic ) InitStatic ();
140 m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( FVF, BVert ), 64 );
141 m_Fbuf = AddBuffer ( (uchar) BFace, BufSize( FVF, BFace ), 64 );
142 AddAttribute ( m_Vbuf, "pos", sizeof ( AttrPos ), false );
143 AddAttribute ( m_Vbuf, "norm", sizeof ( AttrNorm ) );
148 void Mesh::ClearFVF ()
150 ResetBuffer ( 0, mBuf[0].max );
151 ResetBuffer ( 1, mBuf[0].max );
156 void Mesh::SmoothFVF ( int iter )
158 Vector3DF norm, side;
161 VertFVF *v1, *v2, *v3;
163 face_pos = new AttrPos[ NumFace() ];
165 for (int j=0; j < iter; j++) {
166 // Compute centroid of all faces
167 for (int n=0; n < NumFace(); n++) {
168 f = GetFaceFVF ( n );
169 v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
170 face_pos[n].x = ( v1->x + v2->x + v3->x ) / 3.0;
171 face_pos[n].y = ( v1->y + v2->y + v3->y ) / 3.0;
172 face_pos[n].z = ( v1->z + v2->z + v3->z ) / 3.0;
174 // Compute new vertex positions
177 for (int n=0; n < NumVert(); n++) {
178 v1 = GetVertFVF ( n );
180 hval* fptr = mHeap + v1->flist.pos;
181 for (int j=0; j < v1->flist.cnt; j++) {
182 vec.x += face_pos[ (*fptr) ].x;
183 vec.y += face_pos[ (*fptr) ].y;
184 vec.z += face_pos[ (*fptr) ].z;
187 v1->x = vec.x / (float) v1->flist.cnt;
188 v1->y = vec.y / (float) v1->flist.cnt;
189 v1->z = vec.z / (float) v1->flist.cnt;
195 void Mesh::SetNormalFVF ( int n, Vector3DF norm )
199 int noff = GetAttrOffset ( "norm" );
200 v1 = GetVertFVF ( n );
201 vn = (AttrNorm* ) ((char*) v1 + noff );
208 void Mesh::SetColorFVF ( int n, DWORD clr )
212 int coff = GetAttrOffset ( "color" );
213 if ( coff == -1 ) return;
214 v1 = GetVertFVF ( n );
215 vc = (AttrClr* ) ((char*) v1 + coff );
218 void Mesh::ComputeNormalsFVF ()
220 Vector3DF norm, side;
222 VertFVF *v1, *v2, *v3, *v4;
224 AttrNorm* face_norms;
225 face_norms = new AttrNorm[ NumFace() ];
227 // Clear vertex normals
228 int noff = GetAttrOffset ( "norm" );
229 for (int n=0; n < NumVert(); n++) {
230 v1 = GetVertFVF ( n );
231 vn = (AttrNorm*) ((char*) v1 + noff);
237 // Compute normals of all faces
238 for (int n=0; n < NumFace(); n++) {
239 f = GetFaceFVF ( n );
240 v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
241 side = Vector3DF ( v2->x, v2->y, v2->z );
242 side -= Vector3DF ( v1->x, v1->y, v1->z );
244 norm = Vector3DF ( v3->x, v3->y, v3->z );
245 norm -= Vector3DF ( v1->x, v1->y, v1->z );
248 face_norms[n].nx = norm.x;
249 face_norms[n].ny = norm.y;
250 face_norms[n].nz = norm.z;
251 vn = (AttrNorm*) ((char*) v1 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
252 vn = (AttrNorm*) ((char*) v2 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
253 vn = (AttrNorm*) ((char*) v3 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
255 v4 = GetVertFVF(f->v4);
256 vn = (AttrNorm*) ((char*) v4 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
260 // Normalize vertex normals
262 for (int n=0; n < NumVert(); n++) {
263 v1 = GetVertFVF ( n );
264 vn = (AttrNorm*) ((char*) v1 + noff);
265 vec.Set ( vn->nx, vn->ny, vn->nz );
272 // Compute normal of a vertex from surrounding faces (slow method)
274 for (int n=0; n < NumVert(); n++) {
275 v1 = GetVertFVF ( n );
276 vn = (VertNorm*) GetExtraFVF ( v1 );
278 vn->nx = 0; vn->ny = 0; vn->nz = 0;
279 hval* fptr = mHeap + v1->flist.pos;
280 for (int j=0; j < v1->flist.cnt; j++) {
281 vn->nx += face_norms[ (*fptr) ].nx;
282 vn->ny += face_norms[ (*fptr) ].ny;
283 vn->nz += face_norms[ (*fptr) ].nz;
287 vn->nx /= (float) cnt;
288 vn->ny /= (float) cnt;
289 vn->nz /= (float) cnt;
295 void Mesh::SetFuncFVF ()
297 m_AddVertFunc = &Mesh::AddVertFVF;
298 m_AddFaceFast3Func = &Mesh::AddFaceFast3FVF;
299 m_AddFaceFast4Func = &Mesh::AddFaceFast4FVF;
302 xref Mesh::AddFaceFast3FVF ( xref v1, xref v2, xref v3 )
305 FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
306 f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
307 AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
308 AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
309 AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
312 xref Mesh::AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 )
315 FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
316 f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
317 AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
318 AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
319 AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
320 AddRef ( fNdx, GetVertFVF(v4)->flist, FACE_DELTA );
323 xref Mesh::AddVertFVF ( float x, float y, float z )
326 VertFVF* v = (VertFVF*) AddElem ( m_Vbuf, ndx );
327 v->x = x; v->y = y; v->z = z;
328 ClearRefs ( v->flist );
332 void Mesh::DebugFVF ()
338 debug.Printf ( "-- MESH --\n");
340 debug.Printf ( "-- verts\n" );
341 for (n=0; n < NumVert(); n++) {
343 debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) f:%d %d{", n, v->x, v->y, v->z, v->flist.cnt, v->flist.pos);
344 if ( v->flist.cnt > 0 ) {
345 for (j=0; j < v->flist.cnt; j++)
346 debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
348 debug.Printf ( "}\n" );
350 debug.Printf ( "-- faces\n" );
351 for (n=0; n < NumFace(); n++) {
353 debug.Printf ( "%d: v:%d %d %d\n", n, f->v1, f->v2, f->v3);
358 debug.Printf ("\n\n");
363 //------------------------------------------------------------------ CM - Connected Mesh
364 // Create Connected Mesh (CM)
365 void Mesh::CreateCM ()
367 if ( !mbInitStatic ) InitStatic ();
371 m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( CM, BVert ), 64 );
372 m_Ebuf = AddBuffer ( (uchar) BEdge, BufSize ( CM, BEdge), 64 );
373 m_Fbuf = AddBuffer ( (uchar) BFace, BufSize ( CM, BFace), 64 );
374 AddAttribute ( m_Vbuf, "pos", sizeof(AttrPos), false );
375 AddAttribute ( m_Vbuf, "norm", sizeof(AttrNorm) );
380 void Mesh::SetFuncCM ()
382 m_AddVertFunc = &Mesh::AddVertCM;
383 m_AddFaceFast3Func = &Mesh::AddFaceFast3CM;
384 m_AddFaceFast4Func = &Mesh::AddFaceFast4CM;
388 xref Mesh::AddVertCM ( float x, float y, float z )
391 VertCM* v = (VertCM*) AddElem ( m_Vbuf, ndx );
392 v->x = x; v->y = y; v->z = z;
393 ClearRefs ( v->elist );
394 ClearRefs ( v->flist );
398 xref Mesh::AddFaceFast3CM ( xref v1, xref v2, xref v3 )
401 FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
402 f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
404 eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
405 eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
406 eNdx = AddEdgeCM ( f->v3, f->v1 ); f->e3 = eNdx;
407 AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
408 AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
409 AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
412 xref Mesh::AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 )
415 FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
416 f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
418 eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
419 eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
420 eNdx = AddEdgeCM ( f->v3, f->v4 ); f->e3 = eNdx;
421 eNdx = AddEdgeCM ( f->v4, f->v1 ); f->e4 = eNdx;
422 AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
423 AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
424 AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
425 AddRef ( fNdx, GetVertCM(v4)->flist, FACE_DELTA );
429 xref Mesh::FindEdgeCM ( xref v1, xref v2 )
434 if ( pV1->elist.cnt == 0 ) return -1;
435 hval* e = mHeap + pV1->elist.pos;
437 for (int n=0; n < pV1->elist.cnt; n++) {
438 pE = GetEdgeCM( (*e)-EDGE_DELTA );
439 if ( pE->v1 == v2 || pE->v2 == v2 ) return (*e)-EDGE_DELTA;
443 for (int n=0; n < pV1->elist.cnt; n++) {
444 pE = GetEdgeCM( *e );
445 if ( pE->v1 == v2 || pE->v2 == v2 ) return *e;
452 xref Mesh::AddEdgeCM ( xref v1, xref v2 )
454 xref eNdx = FindEdgeCM ( v1, v2 );
455 EdgeCM* e = GetEdgeCM(eNdx);
457 e = (EdgeCM*) AddElem ( m_Ebuf, eNdx );
462 AddRef ( eNdx, GetVertCM(v1)->elist, EDGE_DELTA );
463 AddRef ( eNdx, GetVertCM(v2)->elist, EDGE_DELTA );
468 void Mesh::DebugCM ()
475 debug.Printf ( "-- MESH --\n");
477 debug.Printf ( "-- verts\n" );
478 for (n=0; n < NumVert(); n++) {
480 debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) e:%d %d{", n, v->x, v->y, v->z, v->elist.cnt, v->elist.pos);
481 if ( v->elist.cnt > 0 ) {
482 for (j=0; j < v->elist.cnt; j++)
483 debug.Printf ( "%d ", *(mHeap+v->elist.pos+j) - EDGE_DELTA );
485 debug.Printf ( "}, f:%d %d{", v->flist.cnt, v->flist.pos);
486 if ( v->flist.cnt > 0 ) {
487 for (j=0; j < v->flist.cnt; j++)
488 debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
490 debug.Printf ( "}\n" );
493 debug.Printf ( "-- edges\n" );
494 for (n=0; n < NumEdge(); n++) {
496 debug.Printf ( "%d: v:%d %d, f:%d %d\n", n, e->v1, e->v2, e->f1, e->f2 );
499 debug.Printf ( "-- faces\n" );
500 for (n=0; n < NumFace(); n++) {
502 debug.Printf ( "%d: v:%d %d %d, e:%d %d %d\n", n, f->v1, f->v2, f->v3, f->e1, f->e2, f->e3 );
507 debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
508 for (n=0; n < mHeapNum; n++) {
509 if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
512 debug.Printf ( "00000 ");
513 } else if ( *pVal == (hval) 0xFFFF ) {
514 debug.Printf ( "----- ");
515 } else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
516 debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
517 } else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
518 debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
519 } else if ( *pVal >= FACE_DELTA ) {
520 debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
522 debug.Printf ( "H%04d ", (int) *pVal );
525 debug.Printf ( "%05d ", (int) *pVal );
530 debug.Printf ("\n\n");
534 void Mesh::DebugHeap ()
537 debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
538 for (int n=0; n < mHeapNum; n++) {
539 if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
542 debug.Printf ( "00000 ");
543 } else if ( *pVal == (hval) 0xFFFF ) {
544 debug.Printf ( "----- ");
545 } else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
546 debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
547 } else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
548 debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
549 } else if ( *pVal >= FACE_DELTA ) {
550 debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
552 debug.Printf ( "H%04d ", (int) *pVal );
555 debug.Printf ( "%05d ", (int) *pVal );
561 void Mesh::DrawVertsCM ( float* viewmat, int a, int b )
566 glLoadMatrixf ( viewmat );
567 glTranslatef ( mT.x, mT.y, mT.z );
568 glBegin ( GL_POINTS );
569 for (int n = a; n <= b; n++) {
571 glVertex3f ( v->x, v->y, v->z );
572 //glCallList ( m_GLObj );
577 void Mesh::DrawVertsFVF ( float* viewmat, int a, int b )
581 glLoadMatrixf ( viewmat );
582 glTranslatef ( mT.x, mT.y, mT.z );
583 glBegin ( GL_POINTS );
584 for (int n = a; n <= b; n++) {
586 glVertex3f ( v->x, v->y, v->z );
587 //glCallList ( m_GLObj );
592 void Mesh::DrawFacesCM ( float* viewmat, int a, int b )
597 int noff = GetAttrOffset ( "norm" );
598 glLoadMatrixf ( viewmat );
599 glTranslatef ( mT.x, mT.y, mT.z );
600 GLenum dm = GL_TRIANGLES;
603 for (int n = a; n <= b; n++) {
605 if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
606 v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
607 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
608 v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
609 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
610 v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
611 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
613 if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
614 v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
615 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
616 v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
617 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
618 v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
619 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
620 v = GetVertCM(f->v4); vn = (AttrNorm*) ((char*) v + noff);
621 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
628 void Mesh::DrawFacesFVF ( float* viewmat, int a, int b )
634 int noff = GetAttrOffset ( "norm" );
635 int coff = GetAttrOffset ( "color" );
638 //glLoadMatrixf ( viewmat );
639 //glTranslatef ( mT.x, mT.y, mT.z );
640 GLenum dm = GL_TRIANGLES;
642 f = GetFaceFVF ( a );
643 for (int n = a; n <= b; n++) {
645 if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
646 v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
647 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
648 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
650 v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
651 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
652 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
654 v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
655 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
656 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
658 if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
659 v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
660 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
661 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
663 v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
664 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
665 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
667 v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
668 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
669 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
671 v = GetVertFVF(f->v4); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
672 if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
673 glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
680 void Mesh::DrawEdgesCM ( float* viewmat, int a, int b )
684 glLoadMatrixf ( viewmat );
685 glTranslatef ( mT.x, mT.y, mT.z );
686 glBegin ( GL_LINES );
688 for (int n = a; n <= b; n++) {
689 glVertex3f ( GetVertCM(e->v1)->x, GetVertCM(e->v1)->y, GetVertCM(e->v1)->z );
690 glVertex3f ( GetVertCM(e->v2)->x, GetVertCM(e->v2)->y, GetVertCM(e->v2)->z );
696 void Mesh::DrawGL ( float* viewmat )
702 glDepthRange (0.001, 1.001);
703 //glColor3f ( 1, 0, 0 ); DrawVertsCM ( viewmat, 0, NumVert()-1 );
704 glColor3f ( .6, .6, .6 ); DrawFacesCM ( viewmat, 0, NumFace()-1 );
705 //glDepthRange (0.0005, 1.0005);
706 //glColor3f ( 1, 1, 1); DrawEdgesCM ( viewmat, 0, NumEdge()-1 );
709 //glColor3f (1,0,0); DrawVertsFVF ( viewmat, 0, NumVert()-1 );
710 //glEnable (GL_LIGHTING);
712 glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
713 glColor4f ( .9, .9, .9, 0.75 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
715 /*glDisable (GL_LIGHTING );
716 glDepthRange (0.000, 1.00);
717 glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
719 glColor4f ( 0, 0, 0, 1.0 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
720 glEnable ( GL_LIGHTING );
724 glDepthRange (0.0, 1.0);
725 glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );*/
731 void Mesh::DrawFaceGL ( float* viewmat )
734 if ( m_CurrF < 0 ) m_CurrF = NumFace()-1;
735 if ( m_CurrF >= NumFace() ) m_CurrF = 0;
739 glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
740 DrawFacesFVF ( viewmat, m_CurrF, m_CurrF );
743 glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
744 DrawFacesCM ( viewmat, m_CurrF, m_CurrF );
749 void Mesh::Measure ()
751 hval* pCurr = mHeap + mHeapFree;
752 int vs, es, fs, hs, hm, as, frees = 0;
753 vs = NumVert(); if ( vs !=0 ) vs *= GetStride(m_Vbuf);
754 es = NumEdge(); if ( es !=0 ) es *= GetStride(m_Ebuf);
755 fs = NumFace(); if ( fs !=0 ) fs *= GetStride(m_Fbuf);
756 hs = mHeapNum*sizeof(hval);
757 hm = mHeapMax*sizeof(hval);
759 while ( pCurr != mHeap-1 ) {
761 pCurr = mHeap + * (hpos*) (pCurr + FPOS);
763 frees *= sizeof(hval);
765 if ( m_Vbuf!=-1 ) as += mBuf[m_Vbuf].max * GetStride(m_Vbuf);
766 if ( m_Fbuf!=-1 ) as += mBuf[m_Fbuf].max * GetStride(m_Fbuf);
767 if ( m_Ebuf!=-1 ) as += mBuf[m_Ebuf].max * GetStride(m_Ebuf);
770 debug.Printf ( "NumVert: %07.1fk (%d)\n", vs/1000.0, NumVert() );
771 debug.Printf ( "NumFace: %07.1fk (%d)\n", fs/1000.0, NumFace() );
772 debug.Printf ( "NumEdge: %07.1fk (%d)\n", es/1000.0, NumEdge() );
773 debug.Printf ( "Heap Size: %07.1fk (%d)\n", hs/1000.0, mHeapNum );
774 debug.Printf ( "Free Size: %07.1fk\n", frees/1000.0 );
775 debug.Printf ( "Heap Used: %07.1fk (%5.1f%%)\n", (hs-frees)/1000.0, (hs-frees)*100.0/(vs+es+fs+hs-frees) );
776 debug.Printf ( "Heap Max: %07.1fk\n", hm/1000.0 );
777 debug.Printf ( "Total Used: %07.1fk\n", (vs+es+fs+hs-frees)/1000.0 );
778 debug.Printf ( "Total Alloc: %07.1fk\n", as/1000.0 );
779 debug.Printf ( "Fragmentation: %f%%\n", (hm-(hs-frees))*100.0 / hm );
783 /*int Mesh::GetIndex ( int b, void* v )
785 if ( v == 0x0 ) return -1;
786 return ((char*) v - (char*) mBuf[b].data) / mBuf[b].stride;
789 int Mesh::FindPlyElem ( char typ )
791 for (int n=0; n < m_Ply.size(); n++) {
792 if ( m_Ply[n]->type == typ ) return n;
797 int Mesh::FindPlyProp ( int elem, std::string name )
799 for (int n=0; n < m_Ply[elem]->prop_list.size(); n++) {
800 if ( m_Ply[elem]->prop_list[n].name.compare ( name)==0 )
806 void Mesh::LoadPly ( char* fname, float s )
814 int vnum, fnum, elem, cnt;
817 if ( m_Mform == MFormat::UDef )
820 m_File.Open ( fname, FILE_READ | FILE_SEQUENTIAL );
821 if ( !m_File.Valid() ) {
822 error.PrintF ( "mesh", "Could not find file: %s\n", fname );
827 m_File.ReadLine ( buf, 1000 );
828 b.ReadWord ( buf, bword ); word = bword;
829 if ( word.compare("ply" )!=0 ) {
830 error.PrintF ( "Not a ply file. %s\n", fname );
834 debug.Printf ( "Reading PLY.\n" );
835 while ( m_File.ReadLine ( buf, 1000 ) == FILE_STATUS_OK ) {
836 b.ReadWord ( buf, bword );
838 if ( word.compare("comment" )!=0 ) {
839 if ( word.compare("end_header")==0 ) break;
840 if ( word.compare("property")==0 ) {
841 b.ReadWord ( buf, bword );
843 if ( word.compare("float")==0 ) typ = PLY_FLOAT;
844 if ( word.compare("float16")==0 ) typ = PLY_FLOAT;
845 if ( word.compare("float32")==0 ) typ = PLY_FLOAT;
846 if ( word.compare("int8")==0 ) typ = PLY_INT;
847 if ( word.compare("uint8")==0 ) typ = PLY_UINT;
848 if ( word.compare("list")==0) {
850 b.ReadWord ( buf, bword );
851 b.ReadWord ( buf, bword );
853 b.ReadWord ( buf, bword );
855 AddPlyProperty ( typ, word );
857 if ( word.compare("element" )==0 ) {
858 b.ReadWord ( buf, bword); word = bword;
859 if ( word.compare("vertex")==0 ) {
860 b.ReadWord ( buf, bword);
861 vnum = atoi ( bword );
862 debug.Printf ( " Verts: %d\n", vnum );
863 AddPlyElement ( PLY_VERTS, vnum );
865 if ( word.compare("face")==0 ) {
866 b.ReadWord ( buf, bword);
867 fnum = atoi ( bword );
868 debug.Printf ( " Faces: %d\n", fnum );
869 AddPlyElement ( PLY_FACES, fnum );
877 debug.Printf ( " Reading verts..\n" );
878 elem = FindPlyElem ( PLY_VERTS );
879 xi = FindPlyProp ( elem, "x" );
880 yi = FindPlyProp ( elem, "y" );
881 zi = FindPlyProp ( elem, "z" );
882 if ( elem == -1 || xi == -1 || yi == -1 || zi == -1 ) {
883 debug.Printf ( "ERROR: Vertex data not found.\n" );
886 for (int n=0; n < m_Ply[elem]->num; n++) {
887 m_File.ReadLine ( buf, 1000 );
888 for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
889 b.ReadWord ( buf, bword );
890 m_PlyData[ j ] = atof ( bword );
892 AddVert ( m_PlyData[xi]*s, m_PlyData[zi]*s, m_PlyData[yi]*s );
895 debug.Printf ( " Reading faces..\n" );
896 elem = FindPlyElem ( PLY_FACES );
897 xi = FindPlyProp ( elem, "vertex_indices" );
898 if ( elem == -1 || xi == -1 ) {
899 debug.Printf ( "ERROR: Face data not found.\n" );
902 for (int n=0; n < m_Ply[elem]->num; n++) {
903 m_File.ReadLine ( buf, 1000 );
905 for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
906 if ( m_Ply[elem]->prop_list[j].type == PLY_LIST ) {
907 b.ReadWord ( buf, bword );
908 cnt = atoi ( bword );
909 m_PlyData[ m_PlyCnt++ ] = cnt;
910 for (int c =0; c < cnt; c++) {
911 b.ReadWord ( buf, bword );
912 m_PlyData[ m_PlyCnt++ ] = atof ( bword );
915 b.ReadWord ( buf, bword );
916 m_PlyData[ m_PlyCnt++ ] = atof ( bword );
919 if ( m_PlyData[xi] == 3 ) {
920 //debug.Printf ( " Face: %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
921 AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
924 if ( m_PlyData[xi] == 4 ) {
925 //debug.Printf ( " Face: %d, %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4]);
926 AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4] );
931 ComputeNormalsFVF (); // !-- should be abstracted
937 void Mesh::AddPlyElement ( char typ, int n )
939 debug.Printf ( " Element: %d, %d\n", typ, n );
940 PlyElement* p = new PlyElement;
943 p->prop_list.clear ();
944 m_PlyCurrElem = m_Ply.size();
945 m_Ply.push_back ( p );
948 void Mesh::AddPlyProperty ( char typ, std::string name )
950 debug.Printf ( " Property: %d, %s\n", typ, name.c_str() );
954 m_Ply [ m_PlyCurrElem ]->prop_list.push_back ( p );