|
|
/**
** File : glmesh.cxx ** Description: Implementations of CGlMesh class **/ #include "precomp.h"
#pragma hdrstop
#include "glmesh.h"
#include "pmerrors.h"
/**************************************************************************/
/*
* CGlMesh: Constructor */ CGlMesh::CGlMesh() { //Dynamically allocated arrays
m_matArray = NULL; m_varray = NULL; m_narray = NULL; m_tarray = NULL; m_wedgelist = NULL; m_fnei = NULL; m_facemap = NULL;
m_numFaces = m_numWedges = m_numVerts = m_numMaterials = m_numTextures = 0; }
/*
* CGlMesh: Destructor */ CGlMesh::~CGlMesh() { delete [] m_matArray; delete [] m_varray; delete [] m_narray; delete [] m_tarray; delete [] m_wedgelist; delete [] m_fnei; delete [] m_facemap; }
/*
* CGlMesh: Print */ STDMETHODIMP CGlMesh::Print(ostream& os) {
os << "\n\nMaterials:"; for (int i=0; i<m_numMaterials; ++i) { LPGLmaterial lpglm = &m_matArray[i]; os << "\n\nMaterial [" << i << "] :"; os << "\nShininess : " << lpglm->shininess; os << "\nDiffuse : (" << lpglm->diffuse.r << ", " << lpglm->diffuse.g << ", " << lpglm->diffuse.b << ", " << lpglm->diffuse.a << ")"; os << "\nSpecular : (" << lpglm->specular.r << ", " << lpglm->specular.g << ", " << lpglm->specular.b << ", " << lpglm->specular.a << ")"; os << "\nEmissive : (" << lpglm->emissive.r << ", " << lpglm->emissive.g << ", " << lpglm->emissive.b << ", " << lpglm->emissive.a << ")"; os << "\nNumber of faces: " << m_matcnt[i]; for (int j=0; j< m_matcnt[i]; j++) { #ifdef __MATPOS_IS_A_PTR
os << "\n(" << m_matpos[i][j].w[0] << "," << (m_matpos[i][j]).w[1] << "," << (m_matpos[i][j]).w[2] << ")"; #else
os << "\n(" << (m_farray[m_matpos[i] + j]).w[0] << "," << (m_farray[m_matpos[i] + j]).w[0] << "," << (m_farray[m_matpos[i] + j]).w[0] << ")"; #endif
} }
os << "\n\nWedge connectivity:"; for (i=0; i<m_numWedges; ++i) { os << "\n" << m_wedgelist[i]; } os << "\n\nWedge data:"; for (i=0; i<m_numWedges; ++i) { os << "\n(" << m_varray[i].x << ", " << m_varray[i].y << ", " << m_varray[i].z << ") " << " (" << m_narray[i].x << ", " << m_narray[i].y << ", " << m_narray[i].z << ") " << " (" << m_tarray[i].s << ", " << m_tarray[i].t << ") "; } return S_OK; }
/*
* CGlMesh: Render */ STDMETHODIMP CGlMesh::Render(RenderType rt) { if (rt == GLPM_SOLID) { glVertexPointer(3, GL_FLOAT, 0, (void *)&(m_varray[0].x)); glNormalPointer (GL_FLOAT, 0, (void *)&(m_narray[0].x)); glTexCoordPointer (2, GL_FLOAT, 0, (void *)&(m_tarray[0].s)); glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_NORMAL_ARRAY); for (int i=0; i<m_numMaterials; i++) { LPGLmaterial lpglm = &(m_matArray[i]); if (m_matcnt[i] == (WORD) 0) continue; glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lpglm->shininess); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *) &(lpglm->specular)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (GLfloat *) &(lpglm->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (GLfloat *) &(lpglm->emissive)); glDrawElements (GL_TRIANGLES, (GLuint) m_matcnt[i]*3, GL_UNSIGNED_SHORT, #ifdef __MATPOS_IS_A_PTR
(void *) m_matpos[i]); #else
(void *) &(m_farray[m_matpos[i]])); #endif
} return S_OK; } else { return E_NOTIMPL; } }
PHASHENTRY* hashtable; PHASHENTRY hashentries; int freeptr, maxptr;
void CGlMesh::HashAdd(WORD va, WORD vb, WORD f) { #ifdef _DEBUG
if (va > m_numWedges || va < 0) throw CHashOvrflw(); #endif
for (PHASHENTRY* t = &(hashtable[va]); *t; t = &((*t)->next)); PHASHENTRY p = &(hashentries[freeptr++]); p->f = f; p->v2 = vb; p->next = NULL; *t=p; }
WORD CGlMesh::HashFind(WORD va, WORD vb) { #ifdef _DEBUG
if (va > m_baseWedges || va < 0) throw CHashOvrflw(); #endif
for (PHASHENTRY* t = &(hashtable[va]); *t; t = &((*t)->next)) { if ((*t)->v2 == vb) { return (*t)->f; } } return USHRT_MAX; }
void CGlMesh::ComputeAdjacency(void) { freeptr = 0; maxptr = m_numFaces*3; hashtable = new PHASHENTRY[m_numWedges];
// An entry for each 3 edges of each face in base mesh
hashentries = new hashentry[maxptr]; if (!hashtable) throw CExNewFailed(); memset(hashtable, 0, sizeof(PHASHENTRY)*m_numWedges);
/*
* For each group of faces */ for(int i=0; i<m_numMaterials; ++i) { /*
* For each face in the group */ #ifdef __MATPOS_IS_A_PTR
for (int k=0; k<m_matcnt[i]; ++k) { int v1 = FindVertexIndex((m_matpos[i][k]).w[0]); int v2 = FindVertexIndex((m_matpos[i][k]).w[1]); int v3 = FindVertexIndex((m_matpos[i][k]).w[2]); int fi = GetFaceIndex(i,k); HashAdd(v1,v2,fi); HashAdd(v2,v3,fi); HashAdd(v3,v1,fi); } #else
for (int k=m_matpos[i]; k<(m_matpos[i]+m_matcnt[i]); ++k) { int v1 = FindVertexIndex((m_farray[k]).w[0]); int v2 = FindVertexIndex((m_farray[k]).w[1]); int v3 = FindVertexIndex((m_farray[k]).w[2]); HashAdd(v1,v2,k); HashAdd(v2,v3,k); HashAdd(v3,v1,k); } #endif
}
#ifdef _DEBUG
if (freeptr > maxptr) throw CHashOvrflw(); #endif
/*
* For each group of faces */ for(i=0; i<m_numMaterials; ++i) { /*
* For each face in the group */ #ifdef __MATPOS_IS_A_PTR
for (int k=0; k<m_matcnt[i]; ++k) { int v1 = FindVertexIndex((m_matpos[i][k]).w[0]); int v2 = FindVertexIndex((m_matpos[i][k]).w[1]); int v3 = FindVertexIndex((m_matpos[i][k]).w[2]);
int fi = GetFaceIndex(i,k); m_fnei[fi][0] = HashFind(v3,v2); m_fnei[fi][1] = HashFind(v1,v3); m_fnei[fi][2] = HashFind(v2,v1); } #else
for (int k=m_matpos[i]; k<(m_matpos[i]+m_matcnt[i]); ++k) { int v1 = FindVertexIndex((m_farray[k]).w[0]); int v2 = FindVertexIndex((m_farray[k]).w[1]); int v3 = FindVertexIndex((m_farray[k]).w[2]);
m_fnei[k][0] = HashFind(v3,v2); m_fnei[k][1] = HashFind(v1,v3); m_fnei[k][2] = HashFind(v2,v1); } #endif
} delete [] hashtable; delete [] hashentries; }
#if 0
STDMETHODIMP AddWedge (WORD vertex_id, GLnormal& n, GLtexCoord& t, DWORD* const wedge_id) { WORD w; w = m_numWedges++; m_wedgelist[w] = m_wedgelist[vertex_id]; m_wedgelist[vertex_id] = w; m_varray[w] = m_varray[vertex_id]; m_narray[w] = n; m_tarray[w] = t; *wedge_id = w; return S_OK; }
STDMETHODIMP AddWedge (Glvertex &v, GLnormal& n, GLtexCoord& t, DWORD* const wedge_id) { WORD w; w = m_numWedges++; m_wedgelist[w] = w; m_varray[w] = v; m_narray[w] = n; m_tarray[w] = t; *wedge_id = w; return S_OK; }
STDMETHODIMP AddWedge (Glvertex &v) { WORD w; w = m_numWedges++; m_wedgelist[w] = w; m_varray[w] = v; //m_narray[w] = n;
//m_tarray[w] = t;
*wedge_id = w; return S_OK; }
STDMETHODIMP AddWedge (WORD vertex_id, WORD old_wedge_id, DWORD* const wedge_id) { WORD w; w = m_numWedges++;
/*
* Add wnl to the list of wedges sharing vertex_id */ m_wedgelist[w] = m_wedgelist[vertex_id]; m_wedgelist[vertex_id] = w; /*
* Copy wedge attributes */ m_varray[w] = m_varray[vertex_id]; m_narray[w] = m_narray[old_wedge_id]; m_tarray[w] = m_tarray[old_wedge_id]; *wedge_id = w; return S_OK; }
STDMETHODIMP AddFace (WORD matid, GLface& f) { return S_OK; } #endif
|