Saxum/extern/bullet/Extras/sph/common/mesh.cpp
Fabian Klemp aeb6218d2d Renaming.
2014-10-24 11:49:46 +02:00

955 lines
27 KiB
C++

/*
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
ZLib license
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <conio.h>
#include <vector.h>
#include "mesh.h"
#include "mdebug.h"
//#include "mfile.h"
//#include "event.h"
#include <gl/glut.h>
#define DEGtoRAD (3.141592/180.0)
bool Mesh::mbInitStatic = false;
int Mesh::miBufSize[MAX_MFORMAT][MAX_BFORMAT];
Mesh::Mesh ()
{
debug.SendToConsole ( true );
m_Mform = MFormat::UDef;
m_CurrF = 0;
m_Vbuf = BUF_UNDEF;
m_Ebuf = BUF_UNDEF;
m_Fbuf = BUF_UNDEF;
}
Mesh& Mesh::operator= ( Mesh& src )
{
CopyBuffers ( src );
CopyAttributes ( src );
m_Mform = src.GetMeshBufs ( m_Vbuf, m_Ebuf, m_Fbuf );
return *this;
}
void Mesh::InitStatic ()
{
mbInitStatic = true;
miBufSize[ (int) FVF ][ (int) BVert ] = sizeof ( VertFVF );
miBufSize[ (int) FVF ][ (int) BFace ] = sizeof ( FaceFVF );
miBufSize[ (int) FVF ][ (int) BEdge ] = 0;
miBufSize[ (int) CM ][ (int) BVert ] = sizeof ( VertCM );
miBufSize[ (int) CM ][ (int) BEdge ] = sizeof ( EdgeCM );
miBufSize[ (int) CM ][ (int) BFace ] = sizeof ( FaceCM );
}
/*void Mesh::onUpdate ( objData dat, mint::Event* e )
{
uchar dtype;
hval num;
hval max;
long size;
ushort stride;
int num_buf;
switch ( dat ) {
case 'full':
ClearBuffers ();
ClearAttributes ();
m_Mform = (MFormat) e->getUChar ();
m_Vbuf = e->getUChar ();
m_Ebuf = e->getUChar ();
m_Fbuf = e->getUChar ();
num_buf = e->getInt ();
for (int b=0; b < num_buf; b++) {
dtype = e->getUChar ();
stride = e->getUShort ();
num = e->getInt ();
max = e->getInt ();
AddBuffer ( dtype, stride, max );
e->getMem ( mBuf[b].data, num * mBuf[b].stride );
mBuf[b].num = num;
}
mHeapNum = e->getInt ();
mHeapMax = e->getInt ();
mHeapFree = e->getInt ();
mHeap = new hval[mHeapMax];
e->getMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
break;
};
}
void Mesh::UpdateMesh ()
{
int s = GetSize () + (mBuf.size()+1)*4*sizeof(int);
mint::Event* e = updateStart ( 'full', s );
e->attachUChar ( (char) m_Mform ) ;
e->attachUChar ( (char) m_Vbuf );
e->attachUChar ( (char) m_Ebuf );
e->attachUChar ( (char) m_Fbuf );
e->attachInt ( mBuf.size() );
for (int b=0; b < mBuf.size(); b++) {
e->attachUChar ( mBuf[b].dtype );
e->attachUShort ( mBuf[b].stride );
e->attachInt ( mBuf[b].num );
e->attachInt ( mBuf[b].max );
e->attachMem ( mBuf[b].data, mBuf[b].num * mBuf[b].stride );
}
e->attachInt ( mHeapNum );
e->attachInt ( mHeapMax );
e->attachInt ( mHeapFree );
e->attachMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
updateEnd ( e );
}
*/
//------------------------------------------------------------------ FVF - Face-vertex-face Mesh
void Mesh::CreateFVF ()
{
if ( !mbInitStatic ) InitStatic ();
SetFuncFVF ();
m_Mform = FVF;
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( FVF, BVert ), 64 );
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize( FVF, BFace ), 64 );
AddAttribute ( m_Vbuf, "pos", sizeof ( AttrPos ), false );
AddAttribute ( m_Vbuf, "norm", sizeof ( AttrNorm ) );
AddHeap ( 128 );
}
void Mesh::ClearFVF ()
{
ResetBuffer ( 0, mBuf[0].max );
ResetBuffer ( 1, mBuf[0].max );
ResetHeap ();
}
void Mesh::SmoothFVF ( int iter )
{
Vector3DF norm, side;
int cnt;
FaceFVF* f;
VertFVF *v1, *v2, *v3;
AttrPos* face_pos;
face_pos = new AttrPos[ NumFace() ];
for (int j=0; j < iter; j++) {
// Compute centroid of all faces
for (int n=0; n < NumFace(); n++) {
f = GetFaceFVF ( n );
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
face_pos[n].x = ( v1->x + v2->x + v3->x ) / 3.0;
face_pos[n].y = ( v1->y + v2->y + v3->y ) / 3.0;
face_pos[n].z = ( v1->z + v2->z + v3->z ) / 3.0;
}
// Compute new vertex positions
int cnt;
Vector3DF vec;
for (int n=0; n < NumVert(); n++) {
v1 = GetVertFVF ( n );
vec.Set (0,0,0);
hval* fptr = mHeap + v1->flist.pos;
for (int j=0; j < v1->flist.cnt; j++) {
vec.x += face_pos[ (*fptr) ].x;
vec.y += face_pos[ (*fptr) ].y;
vec.z += face_pos[ (*fptr) ].z;
fptr++;
}
v1->x = vec.x / (float) v1->flist.cnt;
v1->y = vec.y / (float) v1->flist.cnt;
v1->z = vec.z / (float) v1->flist.cnt;
}
}
delete face_pos;
}
void Mesh::SetNormalFVF ( int n, Vector3DF norm )
{
VertFVF* v1;
AttrNorm* vn;
int noff = GetAttrOffset ( "norm" );
v1 = GetVertFVF ( n );
vn = (AttrNorm* ) ((char*) v1 + noff );
vn->nx = norm.x;
vn->ny = norm.y;
vn->nz = norm.z;
}
void Mesh::SetColorFVF ( int n, DWORD clr )
{
VertFVF* v1;
AttrClr* vc;
int coff = GetAttrOffset ( "color" );
if ( coff == -1 ) return;
v1 = GetVertFVF ( n );
vc = (AttrClr* ) ((char*) v1 + coff );
vc->clr = clr;
}
void Mesh::ComputeNormalsFVF ()
{
Vector3DF norm, side;
FaceFVF* f;
VertFVF *v1, *v2, *v3, *v4;
AttrNorm* vn;
AttrNorm* face_norms;
face_norms = new AttrNorm[ NumFace() ];
// Clear vertex normals
int noff = GetAttrOffset ( "norm" );
for (int n=0; n < NumVert(); n++) {
v1 = GetVertFVF ( n );
vn = (AttrNorm*) ((char*) v1 + noff);
vn->nx = 0;
vn->ny = 0;
vn->nz = 0;
}
// Compute normals of all faces
for (int n=0; n < NumFace(); n++) {
f = GetFaceFVF ( n );
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
side = Vector3DF ( v2->x, v2->y, v2->z );
side -= Vector3DF ( v1->x, v1->y, v1->z );
side.Normalize ();
norm = Vector3DF ( v3->x, v3->y, v3->z );
norm -= Vector3DF ( v1->x, v1->y, v1->z );
norm.Normalize ();
norm.Cross ( side );
face_norms[n].nx = norm.x;
face_norms[n].ny = norm.y;
face_norms[n].nz = norm.z;
vn = (AttrNorm*) ((char*) v1 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
vn = (AttrNorm*) ((char*) v2 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
vn = (AttrNorm*) ((char*) v3 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
if ( f->v4 != -1 ) {
v4 = GetVertFVF(f->v4);
vn = (AttrNorm*) ((char*) v4 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
}
}
// Normalize vertex normals
Vector3DF vec;
for (int n=0; n < NumVert(); n++) {
v1 = GetVertFVF ( n );
vn = (AttrNorm*) ((char*) v1 + noff);
vec.Set ( vn->nx, vn->ny, vn->nz );
vec.Normalize ();
vn->nx = vec.x;
vn->ny = vec.y;
vn->nz = vec.z;
}
// Compute normal of a vertex from surrounding faces (slow method)
/*int cnt;
for (int n=0; n < NumVert(); n++) {
v1 = GetVertFVF ( n );
vn = (VertNorm*) GetExtraFVF ( v1 );
cnt = 0;
vn->nx = 0; vn->ny = 0; vn->nz = 0;
hval* fptr = mHeap + v1->flist.pos;
for (int j=0; j < v1->flist.cnt; j++) {
vn->nx += face_norms[ (*fptr) ].nx;
vn->ny += face_norms[ (*fptr) ].ny;
vn->nz += face_norms[ (*fptr) ].nz;
cnt++;
fptr++;
}
vn->nx /= (float) cnt;
vn->ny /= (float) cnt;
vn->nz /= (float) cnt;
}*/
delete face_norms;
}
void Mesh::SetFuncFVF ()
{
m_AddVertFunc = &Mesh::AddVertFVF;
m_AddFaceFast3Func = &Mesh::AddFaceFast3FVF;
m_AddFaceFast4Func = &Mesh::AddFaceFast4FVF;
}
xref Mesh::AddFaceFast3FVF ( xref v1, xref v2, xref v3 )
{
xref fNdx;
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
return fNdx;
}
xref Mesh::AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 )
{
xref fNdx;
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertFVF(v4)->flist, FACE_DELTA );
return fNdx;
}
xref Mesh::AddVertFVF ( float x, float y, float z )
{
xref ndx;
VertFVF* v = (VertFVF*) AddElem ( m_Vbuf, ndx );
v->x = x; v->y = y; v->z = z;
ClearRefs ( v->flist );
return ndx;
}
void Mesh::DebugFVF ()
{
int n;
int j;
VertFVF* v;
FaceFVF* f;
debug.Printf ( "-- MESH --\n");
debug.Printf ( "-- verts\n" );
for (n=0; n < NumVert(); n++) {
v = GetVertFVF(n);
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);
if ( v->flist.cnt > 0 ) {
for (j=0; j < v->flist.cnt; j++)
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
}
debug.Printf ( "}\n" );
}
debug.Printf ( "-- faces\n" );
for (n=0; n < NumFace(); n++) {
f = GetFaceFVF(n);
debug.Printf ( "%d: v:%d %d %d\n", n, f->v1, f->v2, f->v3);
}
DebugHeap ();
debug.Printf ("\n\n");
//_getch();
}
//------------------------------------------------------------------ CM - Connected Mesh
// Create Connected Mesh (CM)
void Mesh::CreateCM ()
{
if ( !mbInitStatic ) InitStatic ();
SetFuncCM ();
m_Mform = CM;
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( CM, BVert ), 64 );
m_Ebuf = AddBuffer ( (uchar) BEdge, BufSize ( CM, BEdge), 64 );
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize ( CM, BFace), 64 );
AddAttribute ( m_Vbuf, "pos", sizeof(AttrPos), false );
AddAttribute ( m_Vbuf, "norm", sizeof(AttrNorm) );
AddHeap ( 128 );
}
void Mesh::SetFuncCM ()
{
m_AddVertFunc = &Mesh::AddVertCM;
m_AddFaceFast3Func = &Mesh::AddFaceFast3CM;
m_AddFaceFast4Func = &Mesh::AddFaceFast4CM;
}
xref Mesh::AddVertCM ( float x, float y, float z )
{
xref ndx;
VertCM* v = (VertCM*) AddElem ( m_Vbuf, ndx );
v->x = x; v->y = y; v->z = z;
ClearRefs ( v->elist );
ClearRefs ( v->flist );
return ndx;
}
xref Mesh::AddFaceFast3CM ( xref v1, xref v2, xref v3 )
{
xref fNdx;
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
xref eNdx;
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
eNdx = AddEdgeCM ( f->v3, f->v1 ); f->e3 = eNdx;
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
return fNdx;
}
xref Mesh::AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 )
{
xref fNdx;
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
xref eNdx;
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
eNdx = AddEdgeCM ( f->v3, f->v4 ); f->e3 = eNdx;
eNdx = AddEdgeCM ( f->v4, f->v1 ); f->e4 = eNdx;
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
AddRef ( fNdx, GetVertCM(v4)->flist, FACE_DELTA );
return fNdx;
}
xref Mesh::FindEdgeCM ( xref v1, xref v2 )
{
EdgeCM *pE;
VertCM *pV1;
pV1 = GetVertCM(v1);
if ( pV1->elist.cnt == 0 ) return -1;
hval* e = mHeap + pV1->elist.pos;
#ifdef MESH_DEBUG
for (int n=0; n < pV1->elist.cnt; n++) {
pE = GetEdgeCM( (*e)-EDGE_DELTA );
if ( pE->v1 == v2 || pE->v2 == v2 ) return (*e)-EDGE_DELTA;
e++;
}
#else
for (int n=0; n < pV1->elist.cnt; n++) {
pE = GetEdgeCM( *e );
if ( pE->v1 == v2 || pE->v2 == v2 ) return *e;
e++;
}
#endif
return -1;
}
xref Mesh::AddEdgeCM ( xref v1, xref v2 )
{
xref eNdx = FindEdgeCM ( v1, v2 );
EdgeCM* e = GetEdgeCM(eNdx);
if ( eNdx == -1 ) {
e = (EdgeCM*) AddElem ( m_Ebuf, eNdx );
e->f1 = 0;
e->f2 = 0;
e->v1 = v1;
e->v2 = v2;
AddRef ( eNdx, GetVertCM(v1)->elist, EDGE_DELTA );
AddRef ( eNdx, GetVertCM(v2)->elist, EDGE_DELTA );
}
return eNdx;
}
void Mesh::DebugCM ()
{
int n;
int j;
VertCM* v;
EdgeCM* e;
FaceCM* f;
debug.Printf ( "-- MESH --\n");
debug.Printf ( "-- verts\n" );
for (n=0; n < NumVert(); n++) {
v = GetVertCM(n);
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);
if ( v->elist.cnt > 0 ) {
for (j=0; j < v->elist.cnt; j++)
debug.Printf ( "%d ", *(mHeap+v->elist.pos+j) - EDGE_DELTA );
}
debug.Printf ( "}, f:%d %d{", v->flist.cnt, v->flist.pos);
if ( v->flist.cnt > 0 ) {
for (j=0; j < v->flist.cnt; j++)
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
}
debug.Printf ( "}\n" );
}
debug.Printf ( "-- edges\n" );
for (n=0; n < NumEdge(); n++) {
e = GetEdgeCM (n);
debug.Printf ( "%d: v:%d %d, f:%d %d\n", n, e->v1, e->v2, e->f1, e->f2 );
}
debug.Printf ( "-- faces\n" );
for (n=0; n < NumFace(); n++) {
f = GetFaceCM(n);
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 );
}
hval* pVal = mHeap;
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
for (n=0; n < mHeapNum; n++) {
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
#ifdef MESH_DEBUG
if ( *pVal == 0 ) {
debug.Printf ( "00000 ");
} else if ( *pVal == (hval) 0xFFFF ) {
debug.Printf ( "----- ");
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
} else if ( *pVal >= FACE_DELTA ) {
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
} else {
debug.Printf ( "H%04d ", (int) *pVal );
}
#else
debug.Printf ( "%05d ", (int) *pVal );
#endif
pVal++;
}
debug.Printf ("\n\n");
//_getch();
}
void Mesh::DebugHeap ()
{
hval* pVal = mHeap;
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
for (int n=0; n < mHeapNum; n++) {
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
#ifdef MESH_DEBUG
if ( *pVal == 0 ) {
debug.Printf ( "00000 ");
} else if ( *pVal == (hval) 0xFFFF ) {
debug.Printf ( "----- ");
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
} else if ( *pVal >= FACE_DELTA ) {
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
} else {
debug.Printf ( "H%04d ", (int) *pVal );
}
#else
debug.Printf ( "%05d ", (int) *pVal );
#endif
pVal++;
}
}
void Mesh::DrawVertsCM ( float* viewmat, int a, int b )
{
VertCM* v;
glColor3f (1,0,0);
glLoadMatrixf ( viewmat );
glTranslatef ( mT.x, mT.y, mT.z );
glBegin ( GL_POINTS );
for (int n = a; n <= b; n++) {
v = GetVertCM (n);
glVertex3f ( v->x, v->y, v->z );
//glCallList ( m_GLObj );
}
glEnd ();
}
void Mesh::DrawVertsFVF ( float* viewmat, int a, int b )
{
VertFVF* v;
glColor3f (1,0,0);
glLoadMatrixf ( viewmat );
glTranslatef ( mT.x, mT.y, mT.z );
glBegin ( GL_POINTS );
for (int n = a; n <= b; n++) {
v = GetVertFVF (n);
glVertex3f ( v->x, v->y, v->z );
//glCallList ( m_GLObj );
}
glEnd ();
}
void Mesh::DrawFacesCM ( float* viewmat, int a, int b )
{
FaceCM* f;
VertCM* v;
AttrNorm* vn;
int noff = GetAttrOffset ( "norm" );
glLoadMatrixf ( viewmat );
glTranslatef ( mT.x, mT.y, mT.z );
GLenum dm = GL_TRIANGLES;
glBegin ( dm );
f = GetFaceCM ( a );
for (int n = a; n <= b; n++) {
if ( f->v4 == -1 ) {
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
} else {
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertCM(f->v4); vn = (AttrNorm*) ((char*) v + noff);
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
}
f++;
}
glEnd ();
}
void Mesh::DrawFacesFVF ( float* viewmat, int a, int b )
{
FaceFVF* f;
VertFVF* v;
AttrNorm* vn;
AttrClr* vc;
int noff = GetAttrOffset ( "norm" );
int coff = GetAttrOffset ( "color" );
coff = -1;
//glLoadMatrixf ( viewmat );
//glTranslatef ( mT.x, mT.y, mT.z );
GLenum dm = GL_TRIANGLES;
glBegin ( dm );
f = GetFaceFVF ( a );
for (int n = a; n <= b; n++) {
if ( f->v4 == -1 ) {
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
} else {
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
v = GetVertFVF(f->v4); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
}
f++;
}
glEnd ();
}
void Mesh::DrawEdgesCM ( float* viewmat, int a, int b )
{
EdgeCM* e;
glLoadMatrixf ( viewmat );
glTranslatef ( mT.x, mT.y, mT.z );
glBegin ( GL_LINES );
e = GetEdgeCM ( a );
for (int n = a; n <= b; n++) {
glVertex3f ( GetVertCM(e->v1)->x, GetVertCM(e->v1)->y, GetVertCM(e->v1)->z );
glVertex3f ( GetVertCM(e->v2)->x, GetVertCM(e->v2)->y, GetVertCM(e->v2)->z );
e++;
}
glEnd ();
}
void Mesh::DrawGL ( float* viewmat )
{
mT.Set(0,0,0);
switch ( m_Mform ) {
case CM: {
glDepthRange (0.001, 1.001);
//glColor3f ( 1, 0, 0 ); DrawVertsCM ( viewmat, 0, NumVert()-1 );
glColor3f ( .6, .6, .6 ); DrawFacesCM ( viewmat, 0, NumFace()-1 );
//glDepthRange (0.0005, 1.0005);
//glColor3f ( 1, 1, 1); DrawEdgesCM ( viewmat, 0, NumEdge()-1 );
} break;
case FVF: {
//glColor3f (1,0,0); DrawVertsFVF ( viewmat, 0, NumVert()-1 );
//glEnable (GL_LIGHTING);
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
glColor4f ( .9, .9, .9, 0.75 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
/*glDisable (GL_LIGHTING );
glDepthRange (0.000, 1.00);
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth ( 3 );
glColor4f ( 0, 0, 0, 1.0 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
glEnable ( GL_LIGHTING );
glLineWidth ( 1);
glDepthRange (0.0, 1.0);
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );*/
} break;
}
}
void Mesh::DrawFaceGL ( float* viewmat )
{
mT.Set (0,0,0);
if ( m_CurrF < 0 ) m_CurrF = NumFace()-1;
if ( m_CurrF >= NumFace() ) m_CurrF = 0;
switch ( m_Mform ) {
case FVF:
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
DrawFacesFVF ( viewmat, m_CurrF, m_CurrF );
break;
case CM:
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
DrawFacesCM ( viewmat, m_CurrF, m_CurrF );
break;
};
}
void Mesh::Measure ()
{
hval* pCurr = mHeap + mHeapFree;
int vs, es, fs, hs, hm, as, frees = 0;
vs = NumVert(); if ( vs !=0 ) vs *= GetStride(m_Vbuf);
es = NumEdge(); if ( es !=0 ) es *= GetStride(m_Ebuf);
fs = NumFace(); if ( fs !=0 ) fs *= GetStride(m_Fbuf);
hs = mHeapNum*sizeof(hval);
hm = mHeapMax*sizeof(hval);
while ( pCurr != mHeap-1 ) {
frees += *(pCurr);
pCurr = mHeap + * (hpos*) (pCurr + FPOS);
}
frees *= sizeof(hval);
as = 0;
if ( m_Vbuf!=-1 ) as += mBuf[m_Vbuf].max * GetStride(m_Vbuf);
if ( m_Fbuf!=-1 ) as += mBuf[m_Fbuf].max * GetStride(m_Fbuf);
if ( m_Ebuf!=-1 ) as += mBuf[m_Ebuf].max * GetStride(m_Ebuf);
as += hm;
debug.Printf ( "NumVert: %07.1fk (%d)\n", vs/1000.0, NumVert() );
debug.Printf ( "NumFace: %07.1fk (%d)\n", fs/1000.0, NumFace() );
debug.Printf ( "NumEdge: %07.1fk (%d)\n", es/1000.0, NumEdge() );
debug.Printf ( "Heap Size: %07.1fk (%d)\n", hs/1000.0, mHeapNum );
debug.Printf ( "Free Size: %07.1fk\n", frees/1000.0 );
debug.Printf ( "Heap Used: %07.1fk (%5.1f%%)\n", (hs-frees)/1000.0, (hs-frees)*100.0/(vs+es+fs+hs-frees) );
debug.Printf ( "Heap Max: %07.1fk\n", hm/1000.0 );
debug.Printf ( "Total Used: %07.1fk\n", (vs+es+fs+hs-frees)/1000.0 );
debug.Printf ( "Total Alloc: %07.1fk\n", as/1000.0 );
debug.Printf ( "Fragmentation: %f%%\n", (hm-(hs-frees))*100.0 / hm );
}
/*int Mesh::GetIndex ( int b, void* v )
{
if ( v == 0x0 ) return -1;
return ((char*) v - (char*) mBuf[b].data) / mBuf[b].stride;
}*/
int Mesh::FindPlyElem ( char typ )
{
for (int n=0; n < m_Ply.size(); n++) {
if ( m_Ply[n]->type == typ ) return n;
}
return -1;
}
int Mesh::FindPlyProp ( int elem, std::string name )
{
for (int n=0; n < m_Ply[elem]->prop_list.size(); n++) {
if ( m_Ply[elem]->prop_list[n].name.compare ( name)==0 )
return n;
}
return -1;
}
void Mesh::LoadPly ( char* fname, float s )
{
/* int m_PlyCnt;
float m_PlyData[40];
char buf[1000];
char bword[1000];
std::string word;
Buffer b(1000);
int vnum, fnum, elem, cnt;
char typ;
if ( m_Mform == MFormat::UDef )
CreateFVF ();
m_File.Open ( fname, FILE_READ | FILE_SEQUENTIAL );
if ( !m_File.Valid() ) {
error.PrintF ( "mesh", "Could not find file: %s\n", fname );
error.Exit ();
}
// Read header
m_File.ReadLine ( buf, 1000 );
b.ReadWord ( buf, bword ); word = bword;
if ( word.compare("ply" )!=0 ) {
error.PrintF ( "Not a ply file. %s\n", fname );
error.Exit ();
}
debug.Printf ( "Reading PLY.\n" );
while ( m_File.ReadLine ( buf, 1000 ) == FILE_STATUS_OK ) {
b.ReadWord ( buf, bword );
word = bword;
if ( word.compare("comment" )!=0 ) {
if ( word.compare("end_header")==0 ) break;
if ( word.compare("property")==0 ) {
b.ReadWord ( buf, bword );
word = bword;
if ( word.compare("float")==0 ) typ = PLY_FLOAT;
if ( word.compare("float16")==0 ) typ = PLY_FLOAT;
if ( word.compare("float32")==0 ) typ = PLY_FLOAT;
if ( word.compare("int8")==0 ) typ = PLY_INT;
if ( word.compare("uint8")==0 ) typ = PLY_UINT;
if ( word.compare("list")==0) {
typ = PLY_LIST;
b.ReadWord ( buf, bword );
b.ReadWord ( buf, bword );
}
b.ReadWord ( buf, bword );
word = bword;
AddPlyProperty ( typ, word );
}
if ( word.compare("element" )==0 ) {
b.ReadWord ( buf, bword); word = bword;
if ( word.compare("vertex")==0 ) {
b.ReadWord ( buf, bword);
vnum = atoi ( bword );
debug.Printf ( " Verts: %d\n", vnum );
AddPlyElement ( PLY_VERTS, vnum );
}
if ( word.compare("face")==0 ) {
b.ReadWord ( buf, bword);
fnum = atoi ( bword );
debug.Printf ( " Faces: %d\n", fnum );
AddPlyElement ( PLY_FACES, fnum );
}
}
}
}
// Read data
int xi, yi, zi;
debug.Printf ( " Reading verts..\n" );
elem = FindPlyElem ( PLY_VERTS );
xi = FindPlyProp ( elem, "x" );
yi = FindPlyProp ( elem, "y" );
zi = FindPlyProp ( elem, "z" );
if ( elem == -1 || xi == -1 || yi == -1 || zi == -1 ) {
debug.Printf ( "ERROR: Vertex data not found.\n" );
exit(-1);
}
for (int n=0; n < m_Ply[elem]->num; n++) {
m_File.ReadLine ( buf, 1000 );
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
b.ReadWord ( buf, bword );
m_PlyData[ j ] = atof ( bword );
}
AddVert ( m_PlyData[xi]*s, m_PlyData[zi]*s, m_PlyData[yi]*s );
}
debug.Printf ( " Reading faces..\n" );
elem = FindPlyElem ( PLY_FACES );
xi = FindPlyProp ( elem, "vertex_indices" );
if ( elem == -1 || xi == -1 ) {
debug.Printf ( "ERROR: Face data not found.\n" );
exit(-1);
}
for (int n=0; n < m_Ply[elem]->num; n++) {
m_File.ReadLine ( buf, 1000 );
m_PlyCnt = 0;
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
if ( m_Ply[elem]->prop_list[j].type == PLY_LIST ) {
b.ReadWord ( buf, bword );
cnt = atoi ( bword );
m_PlyData[ m_PlyCnt++ ] = cnt;
for (int c =0; c < cnt; c++) {
b.ReadWord ( buf, bword );
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
}
} else {
b.ReadWord ( buf, bword );
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
}
}
if ( m_PlyData[xi] == 3 ) {
//debug.Printf ( " Face: %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
}
if ( m_PlyData[xi] == 4 ) {
//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]);
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4] );
}
}
Measure ();
ComputeNormalsFVF (); // !-- should be abstracted
*/
// UpdateMesh ();
}
void Mesh::AddPlyElement ( char typ, int n )
{
debug.Printf ( " Element: %d, %d\n", typ, n );
PlyElement* p = new PlyElement;
p->num = n;
p->type = typ;
p->prop_list.clear ();
m_PlyCurrElem = m_Ply.size();
m_Ply.push_back ( p );
}
void Mesh::AddPlyProperty ( char typ, std::string name )
{
debug.Printf ( " Property: %d, %s\n", typ, name.c_str() );
PlyProperty p;
p.name = name;
p.type = typ;
m_Ply [ m_PlyCurrElem ]->prop_list.push_back ( p );
}