3dObjectLathe.cpp
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:22k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // 3dObjectLathe.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is provided for educational and personal use only and
  11. // is provided without guarantee or warrantee expressed or implied.
  12. //
  13. // Commercial use is strickly prohibited without written permission
  14. // from ImageWare Development.
  15. //
  16. // This program is -not- in the public domain.
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "glOOP.h"
  21. #include "3dObjectDialog.h"
  22. #include <math.h>
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. //////////////////////////////////////////////////////////////////
  29. // C3dObjectLathe
  30. IMPLEMENT_DYNAMIC(C3dObjectLathe, C3dObject)
  31. /////////////////////////////////////////////////////////////////////////////
  32. // C3dShape construction
  33. C3dObjectLathe::C3dObjectLathe()
  34. {
  35. // Set the attributes to default values..
  36.   m_iType = SHAPE_OBJECT;
  37.    m_szName.Format("Lathe %u", nLatheObjects++);
  38. m_fSweepAngle  = 360.0f;
  39. m_iSegments = 20;
  40. m_bSmooth   = TRUE;
  41. m_fMaxAngle = 30.0f;
  42. // Create our C3dPointArray object
  43. m_pPointArray = new C3dPointArray;
  44. ASSERT(m_pPointArray);
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // C3DWorld Destructor
  48. C3dObjectLathe::~C3dObjectLathe()
  49. {
  50. // Delete our point array
  51. if(m_pPointArray)
  52. delete m_pPointArray;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // C3dObjectLathe virtual function overrides
  56. void C3dObjectLathe::AddAttributePage(C3dWorld* pWorld, LPVOID pSht)
  57. {
  58. C3dObjectPropSheet* pSheet = (C3dObjectPropSheet*)pSht;
  59. ASSERT(pSheet);
  60. // Add the page to the property sheet
  61. pSheet->AddPage(&pSheet->m_LathePage);
  62. // Save the address of this object in the page
  63. pSheet->m_LathePage.m_pObject = this;
  64. }
  65. void C3dObjectLathe::GetShapeBounds(C3dBoundingBox* pBox)
  66. {
  67. C3dPoint* pPoint;
  68. // Set to large positive number
  69. pBox->m_fMin[X] = -(GLfloat)LARGE_NUMBER;
  70. pBox->m_fMin[Z] = (GLfloat)LARGE_NUMBER;
  71. // Set to large negative number
  72. pBox->m_fMax[X] = -(GLfloat)LARGE_NUMBER;
  73. pBox->m_fMax[Z] = -(GLfloat)LARGE_NUMBER;
  74. for(int i=0; i<m_pPointArray->m_iNumPoints; i++)
  75. {
  76. pPoint = &m_pPointArray->m_pPoints[i];
  77. if(pPoint->m_fOrigin[X] > pBox->m_fMax[X])
  78. pBox->m_fMax[X] = pPoint->m_fOrigin[X];
  79. if(pPoint->m_fOrigin[Z] > pBox->m_fMax[Z])
  80. pBox->m_fMax[Z] = pPoint->m_fOrigin[Z];
  81. if(pPoint->m_fOrigin[X] > pBox->m_fMin[X])
  82. pBox->m_fMin[X] = pPoint->m_fOrigin[X];
  83. if(pPoint->m_fOrigin[Z] < pBox->m_fMin[Z])
  84. pBox->m_fMin[Z] = pPoint->m_fOrigin[Z];
  85. }
  86. // Since we 'lathe' about the Z-Axis, copy the X-Axis
  87. // values to the Y-Axis
  88. pBox->m_fMax[Y] = pBox->m_fMax[X];
  89. pBox->m_fMin[Y] = pBox->m_fMin[X];
  90. // Since the points array only maps values 'typically' 
  91. // defined along one side of the Z-Axis, negate the min
  92. // values to indicate the 'opposite' side..
  93. pBox->m_fMin[X] *= -1.0f;
  94. pBox->m_fMin[Y] *= -1.0f;
  95. }
  96. int C3dObjectLathe::LoadBitMapImage(CImageList* pList)
  97. {
  98. CBitmap bitmap;
  99. // If the image index has been stored in this object,
  100. // return the index.
  101. if(m_iBMImage > -1)
  102. return m_iBMImage;
  103. // If the image index for this object type has been
  104. // created, store the index for this object and
  105. // return the index.
  106. if( iObjectPlaneBMImage > -1) {
  107. m_iBMImage = iObjectPlaneBMImage;
  108. return m_iBMImage;
  109. }
  110. // The image index for this object type has not been
  111. // loaded and the object image index has not been
  112. // stored.
  113. //
  114. // Load the bitmap for the non-selected light
  115. bitmap.LoadBitmap(IDB_OBJECT_LATHE);
  116. m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  117. bitmap.DeleteObject();
  118. // Load the bitmap for the non-selected light
  119. bitmap.LoadBitmap(IDB_OBJECT_LATHE_SELECTED);
  120. pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  121. bitmap.DeleteObject();
  122. iObjectPlaneBMImage = m_iBMImage;
  123. return m_iBMImage;
  124. }
  125. void C3dObjectLathe::Serialize(CArchive& ar, int iVersion)
  126. {
  127. CString szBuffer;
  128. if (ar.IsStoring())
  129. {
  130. // Save the Object Class header...
  131. szBuffer.Format("n%sC3dObjectLathe {n", szIndent);
  132. ar.WriteString(szBuffer);
  133. // Save the this objects' specific data...
  134. szBuffer.Format("%stSweepAngle    < %f >n", szIndent, m_fSweepAngle);
  135. ar.WriteString(szBuffer);
  136. szBuffer.Format("%stSegments      < %d >n", szIndent, m_iSegments);
  137. ar.WriteString(szBuffer);
  138. szBuffer.Format("%stNum Points    < %d >n", szIndent, m_pPointArray->m_iNumPoints);
  139. ar.WriteString(szBuffer);
  140. for(int i=0; i<m_pPointArray->m_iNumPoints; i++)
  141. {
  142. szBuffer.Format("%stt        < %f, %f, %f >n", szIndent, m_pPointArray->m_pPoints[i].m_fOrigin[0],
  143. m_pPointArray->m_pPoints[i].m_fOrigin[1],
  144. m_pPointArray->m_pPoints[i].m_fOrigin[2]);
  145. ar.WriteString(szBuffer);
  146. }
  147. szBuffer.Format("%stSmooth Faces  < %d >n", szIndent, m_bSmooth);
  148. ar.WriteString(szBuffer);
  149. szBuffer.Format("%stMax Angle     < %f >n", szIndent, m_fMaxAngle);
  150. ar.WriteString(szBuffer);
  151. // Save the base class object data...
  152. C3dObject::Serialize(ar, iVersion);
  153. szBuffer.Format("%s}n", szIndent); // end of object def
  154. ar.WriteString(szBuffer);
  155. }
  156. else
  157. {
  158. if(iVersion < 102)
  159. // Read the base class object data...
  160. C3dObject::Serialize(ar, iVersion);
  161. // Read the derived class data..
  162. ar.ReadString(szBuffer);
  163. szBuffer.TrimLeft(); // Remove leading white spaces
  164. sscanf(szBuffer, "SweepAngle    < %f >n", &m_fSweepAngle);
  165. ar.ReadString(szBuffer);
  166. szBuffer.TrimLeft();
  167. sscanf(szBuffer, "Segments      < %d >n", &m_iSegments);
  168. ar.ReadString(szBuffer);
  169. szBuffer.TrimLeft();
  170. sscanf(szBuffer, "Num Points    < %d >n", &m_pPointArray->m_iNumPoints);
  171. // Create the array of points
  172. if(!m_pPointArray->Create(m_pPointArray->m_iNumPoints))
  173. {
  174. // Now that the points array has been created,
  175. // read the point data.
  176. for(int i=0; i<m_pPointArray->m_iNumPoints; i++)
  177. {
  178. ar.ReadString(szBuffer);
  179. szBuffer.TrimLeft();
  180. sscanf(szBuffer, "< %f, %f, %f >n", &m_pPointArray->m_pPoints[i].m_fOrigin[0],
  181.  &m_pPointArray->m_pPoints[i].m_fOrigin[1],
  182.  &m_pPointArray->m_pPoints[i].m_fOrigin[2]);
  183. }
  184. }
  185. ar.ReadString(szBuffer);
  186. szBuffer.TrimLeft();
  187. sscanf(szBuffer, "Smooth Faces  < %d >n", &m_bSmooth);
  188. ar.ReadString(szBuffer);
  189. szBuffer.TrimLeft();
  190. sscanf(szBuffer, "Max Angle     < %f >n", &m_fMaxAngle);
  191. if(iVersion < 102)
  192. // Read all child objects...
  193. LoadChildObjects(ar, iVersion);
  194. else
  195. // Read the base class object data...
  196. C3dObject::Serialize(ar, iVersion);
  197. }
  198. }
  199. void C3dObjectLathe::Build(C3dWorld* pWorld, C3dCamera* pCamera)
  200. {
  201. GLfloat Theta, DTheta, HalfDTheta;
  202. GLfloat CosThetaMinus, SinThetaMinus;
  203. GLfloat CosThetaPlus, SinThetaPlus;
  204. LatheFace Vertice, Normal;
  205. GLfloat s, t;  // Texture coordinates
  206. int i, j, k;
  207. // Our angles used to define vertices
  208. DTheta=m_fSweepAngle/m_iSegments;
  209. HalfDTheta=DTheta/2;
  210. Theta=HalfDTheta;
  211. s = (1/(m_fSweepAngle/DTheta));
  212. t = (1/(GLfloat)(m_pPointArray->m_iNumPoints-1));
  213. j =  0;
  214. glNewList(m_iDisplayLists, GL_COMPILE_AND_EXECUTE);
  215.  
  216. do {
  217. i=0;
  218. k=m_pPointArray->m_iNumPoints-1;
  219. // Calcualte arc angles used to calcualte our
  220. // planes vertices
  221. CosThetaMinus=Cosf(Theta-HalfDTheta);
  222. SinThetaMinus=Sinf(Theta-HalfDTheta);
  223. CosThetaPlus=Cosf(Theta+HalfDTheta);
  224. SinThetaPlus=Sinf(Theta+HalfDTheta);
  225. do {
  226. // Calculate the plane vertices rotated about the Y-axis
  227. Vertice[0][X]=CosThetaPlus*m_pPointArray->m_pPoints[i].m_fOrigin[0];
  228. Vertice[0][Y]=SinThetaPlus*m_pPointArray->m_pPoints[i].m_fOrigin[0];
  229. Vertice[0][Z]=m_pPointArray->m_pPoints[i].m_fOrigin[2];
  230. Vertice[1][X]=CosThetaMinus*m_pPointArray->m_pPoints[i].m_fOrigin[0];
  231. Vertice[1][Y]=SinThetaMinus*m_pPointArray->m_pPoints[i].m_fOrigin[0];
  232. Vertice[1][Z]=m_pPointArray->m_pPoints[i].m_fOrigin[2];
  233. Vertice[2][X]=CosThetaMinus*m_pPointArray->m_pPoints[i+1].m_fOrigin[0];
  234. Vertice[2][Y]=SinThetaMinus*m_pPointArray->m_pPoints[i+1].m_fOrigin[0];
  235. Vertice[2][Z]=m_pPointArray->m_pPoints[i+1].m_fOrigin[2];
  236. Vertice[3][X]=CosThetaPlus*m_pPointArray->m_pPoints[i+1].m_fOrigin[0];
  237. Vertice[3][Y]=SinThetaPlus*m_pPointArray->m_pPoints[i+1].m_fOrigin[0];
  238. Vertice[3][Z]=m_pPointArray->m_pPoints[i+1].m_fOrigin[2];
  239. // Calculate the surface normals for each
  240. // of our lathe face vertices.
  241. if(m_bSmooth)
  242. CalSmoothNormals(Vertice, i, Theta, Normal);
  243. else
  244. CalNormals(Vertice, Normal);
  245. glBegin(GL_TRIANGLES);
  246. glNormal3f(Normal[0][X], Normal[0][Y], Normal[0][Z]);
  247. glTexCoord2f(s*(j+1), t*(k));
  248. glVertex3d(Vertice[0][X], Vertice[0][Y], Vertice[0][Z]);
  249. glNormal3f(Normal[1][X], Normal[1][Y], Normal[1][Z]);
  250. glTexCoord2f(s*(j), t*(k));
  251. glVertex3d(Vertice[1][X], Vertice[1][Y], Vertice[1][Z]);
  252. glNormal3f(Normal[2][X], Normal[2][Y], Normal[2][Z]);
  253. glTexCoord2f(s*(j), t*(k-1));
  254. glVertex3d(Vertice[2][X], Vertice[2][Y], Vertice[2][Z]);
  255. glTexCoord2f(s*(j), t*(k-1));
  256. glVertex3d(Vertice[2][X], Vertice[2][Y], Vertice[2][Z]);
  257. glNormal3f(Normal[3][X], Normal[3][Y], Normal[3][Z]);
  258. glTexCoord2f(s*(j+1), t*(k-1));
  259. glVertex3d(Vertice[3][X], Vertice[3][Y], Vertice[3][Z]);
  260. glNormal3f(Normal[0][X], Normal[0][Y], Normal[0][Z]);
  261. glTexCoord2f(s*(j+1), t*(k));
  262. glVertex3d(Vertice[0][X], Vertice[0][Y], Vertice[0][Z]);
  263. glEnd();
  264. ++i; // Increment face
  265. --k; // Decrement face
  266. } while(i<m_pPointArray->m_iNumPoints-1);
  267. Theta+=DTheta;
  268. ++j; // Increment segment
  269. } while(Theta<(m_fSweepAngle));
  270. glEndList();
  271. }
  272. /////////////////////////////////////////////////////////////////////////////
  273. // C3dObjectLathe function implimentation
  274. void C3dObjectLathe::CalNormals(LatheFace Vertice, LatheFace Normal)
  275. {
  276. VECTORF u, v;
  277. // Calculate the surface normals for the lathe face
  278. VecSubf(Vertice[3], Vertice[0], u);
  279. VecSubf(Vertice[1], Vertice[0], v);
  280. if(!VecLenf(v))
  281. VecSubf(Vertice[2], Vertice[0], v);
  282. VecCrossf(v, u, Normal[0]);
  283. VecNormalizef(Normal[0]);
  284. VecSubf(Vertice[0], Vertice[1], u);
  285. if(!VecLenf(u))
  286. VecSubf(Vertice[3], Vertice[1], u);
  287. VecSubf(Vertice[2], Vertice[1], v);
  288. VecCrossf(v, u, Normal[1]);
  289. VecNormalizef(Normal[1]);
  290. VecSubf(Vertice[1], Vertice[2], u);
  291. VecSubf(Vertice[3], Vertice[2], v);
  292. if(!VecLenf(v))
  293. VecSubf(Vertice[0], Vertice[2], v);
  294. VecCrossf(v, u, Normal[2]);
  295. VecNormalizef(Normal[2]);
  296. VecSubf(Vertice[2], Vertice[3], u);
  297. if(!VecLenf(u))
  298. VecSubf(Vertice[1], Vertice[3], u);
  299. VecSubf(Vertice[0], Vertice[3], v);
  300. VecCrossf(v, u, Normal[3]);
  301. VecNormalizef(Normal[3]);
  302. }
  303. void C3dObjectLathe::CalSmoothNormals(LatheFace Vertice, int iFace, float fTheta, LatheFace Normal)
  304. {
  305. // This routine calcualtes the surface normal as
  306. // an average of it's surrounding normals as long
  307. // as the angle between adjacent normals is
  308. // within the member variable m_fMaxAngle.
  309. //
  310. //            <Padj 1>     <Padj 0>  
  311. //
  312. //                _____________
  313. // <Padj 2>   P1 |            /| P0    <Padj 7>
  314. //               |          /  |
  315. //               |        /    |
  316. //               |      /      |
  317. //               |    /        |     
  318. //               |  /          |     
  319. // <Padj 3>   P2 |/____________| P3    <Padj 6> 
  320. //
  321. //
  322. //            <Padj 4>     <Padj 5>  
  323. //
  324. GLfloat DTheta, HalfDTheta;
  325. GLfloat CosThetaMinus, SinThetaMinus;
  326. GLfloat CosThetaPlus, SinThetaPlus;
  327. GLfloat CosThetaMinusMinus, SinThetaMinusMinus;
  328. GLfloat CosThetaPlusPlus, SinThetaPlusPlus;
  329. GLfloat fAngle;
  330. VECTORF AdjVertice[8];
  331. VECTORF u, v;
  332. VECTORF AdjNormal;
  333. VECTORF AveNormal;
  334. int iNumAveNormals;
  335. // Our angles used to define vertices
  336. DTheta=m_fSweepAngle/m_iSegments;
  337. HalfDTheta=DTheta/2;
  338. // Arc angles used to calcualte this 
  339. // planes vertices
  340. CosThetaMinus=Cosf(fTheta-HalfDTheta);
  341. SinThetaMinus=Sinf(fTheta-HalfDTheta);
  342. CosThetaPlus=Cosf(fTheta+HalfDTheta);
  343. SinThetaPlus=Sinf(fTheta+HalfDTheta);
  344. // Arc angles used to calcualte our
  345. // planes adjacent vertices
  346. CosThetaMinusMinus=Cosf((fTheta-DTheta)-HalfDTheta);
  347. SinThetaMinusMinus=Sinf((fTheta-DTheta)-HalfDTheta);
  348. CosThetaPlusPlus=Cosf((fTheta+DTheta)+HalfDTheta);
  349. SinThetaPlusPlus=Sinf((fTheta+DTheta)+HalfDTheta);
  350. if(iFace) {
  351. // Calculate the previous planes vertices
  352. AdjVertice[0][X]=CosThetaPlus*m_pPointArray->m_pPoints[iFace-1].m_fOrigin[0];
  353. AdjVertice[0][Y]=SinThetaPlus*m_pPointArray->m_pPoints[iFace-1].m_fOrigin[0];
  354. AdjVertice[0][Z]=m_pPointArray->m_pPoints[iFace-1].m_fOrigin[2];
  355. AdjVertice[1][X]=CosThetaMinus*m_pPointArray->m_pPoints[iFace-1].m_fOrigin[0];
  356. AdjVertice[1][Y]=SinThetaMinus*m_pPointArray->m_pPoints[iFace-1].m_fOrigin[0];
  357. AdjVertice[1][Z]=m_pPointArray->m_pPoints[iFace-1].m_fOrigin[2];
  358. }
  359. // Calculate the left planes vertices
  360. AdjVertice[2][X]=CosThetaMinusMinus*m_pPointArray->m_pPoints[iFace].m_fOrigin[0];
  361. AdjVertice[2][Y]=SinThetaMinusMinus*m_pPointArray->m_pPoints[iFace].m_fOrigin[0];
  362. AdjVertice[2][Z]=m_pPointArray->m_pPoints[iFace].m_fOrigin[2];
  363. AdjVertice[3][X]=CosThetaMinusMinus*m_pPointArray->m_pPoints[iFace+1].m_fOrigin[0];
  364. AdjVertice[3][Y]=SinThetaMinusMinus*m_pPointArray->m_pPoints[iFace+1].m_fOrigin[0];
  365. AdjVertice[3][Z]=m_pPointArray->m_pPoints[iFace+1].m_fOrigin[2];
  366. if(iFace<(m_pPointArray->m_iNumPoints-1)) {
  367. // Calculate the next planes vertices
  368. AdjVertice[4][X]=CosThetaMinus*m_pPointArray->m_pPoints[iFace+2].m_fOrigin[0];
  369. AdjVertice[4][Y]=SinThetaMinus*m_pPointArray->m_pPoints[iFace+2].m_fOrigin[0];
  370. AdjVertice[4][Z]=m_pPointArray->m_pPoints[iFace+2].m_fOrigin[2];
  371. AdjVertice[5][X]=CosThetaPlus*m_pPointArray->m_pPoints[iFace+2].m_fOrigin[0];
  372. AdjVertice[5][Y]=SinThetaPlus*m_pPointArray->m_pPoints[iFace+2].m_fOrigin[0];
  373. AdjVertice[5][Z]=m_pPointArray->m_pPoints[iFace+2].m_fOrigin[2];
  374. }
  375. // Calculate the right planes vertices
  376. AdjVertice[6][X]=CosThetaPlusPlus*m_pPointArray->m_pPoints[iFace+1].m_fOrigin[0];
  377. AdjVertice[6][Y]=SinThetaPlusPlus*m_pPointArray->m_pPoints[iFace+1].m_fOrigin[0];
  378. AdjVertice[6][Z]=m_pPointArray->m_pPoints[iFace+1].m_fOrigin[2];
  379. AdjVertice[7][X]=CosThetaPlusPlus*m_pPointArray->m_pPoints[iFace].m_fOrigin[0];
  380. AdjVertice[7][Y]=SinThetaPlusPlus*m_pPointArray->m_pPoints[iFace].m_fOrigin[0];
  381. AdjVertice[7][Z]=m_pPointArray->m_pPoints[iFace].m_fOrigin[2];
  382. // Now that we have the adjacent face vertices, 
  383. // calculate the average surface normal for each
  384. // face vertice..
  385. ///////////////////////////////////////////////////
  386. // Face Vertice '0' average surface normal:
  387. iNumAveNormals = 0;
  388. VecSubf(Vertice[3], Vertice[0], u);
  389. VecSubf(Vertice[1], Vertice[0], v);
  390. if(!VecLenf(v))
  391. VecSubf(Vertice[2], Vertice[0], v);
  392. VecCrossf(v, u, Normal[0]);
  393. VecCopy3f(Normal[0], AveNormal);
  394. ++iNumAveNormals;
  395. if(iFace) {
  396. VecSubf(Vertice[1], Vertice[0], u);
  397. VecSubf(AdjVertice[0], Vertice[0], v);
  398. VecCrossf(v, u, AdjNormal);
  399. // Calculate angle between the Normal vectors
  400. // where:
  401. // u.v = u1v1 + u2v2 + u3v3
  402. // u.v = |u||v|cos theta
  403. // theta = inv cos(u.v/|u||v|)
  404. //
  405. fAngle = Degreesf( acos( (VecDotf(Normal[0], AdjNormal)) / (VecLenf(Normal[0])*VecLenf(AdjNormal)) ));
  406. if(fAngle <= m_fMaxAngle) {
  407. VecAddf(AveNormal, AdjNormal, AveNormal);
  408. ++iNumAveNormals;
  409. }
  410. VecSubf(AdjVertice[0], Vertice[0], u);
  411. VecSubf(AdjVertice[7], Vertice[0], v);
  412. VecCrossf(v, u, AdjNormal);
  413. // Calculate angle between the Normal vectors
  414. fAngle = Degreesf( acos( (VecDotf(Normal[0], AdjNormal)) / (VecLenf(Normal[0])*VecLenf(AdjNormal)) ));
  415. if(fAngle <= m_fMaxAngle) {
  416. VecAddf(AveNormal, AdjNormal, AveNormal);
  417. ++iNumAveNormals;
  418. }
  419. }
  420. VecSubf(AdjVertice[7], Vertice[0], u);
  421. VecSubf(Vertice[3], Vertice[0], v);
  422. VecCrossf(v, u, AdjNormal);
  423. // Calculate angle between the Normal vectors
  424. fAngle = Degreesf( acos( (VecDotf(Normal[0], AdjNormal)) / (VecLenf(Normal[0])*VecLenf(AdjNormal)) ));
  425. if(fAngle <= m_fMaxAngle) {
  426. VecAddf(AveNormal, AdjNormal, AveNormal);
  427. ++iNumAveNormals;
  428. }
  429. // Calculate the average surface normal for face
  430. // vertice '0'
  431. Normal[0][X] = AveNormal[X]/iNumAveNormals;
  432. Normal[0][Y] = AveNormal[Y]/iNumAveNormals;
  433. Normal[0][Z] = AveNormal[Z]/iNumAveNormals;
  434. VecNormalizef(Normal[0]);
  435. ///////////////////////////////////////////////////
  436. // Face Vertice '1' average surface normal:
  437. iNumAveNormals = 0;
  438. VecSubf(Vertice[0], Vertice[1], u);
  439. if(!VecLenf(u))
  440. VecSubf(Vertice[3], Vertice[1], u);
  441. VecSubf(Vertice[2], Vertice[1], v);
  442. VecCrossf(v, u, Normal[1]);
  443. VecCopy3f(Normal[1], AveNormal);
  444. ++iNumAveNormals;
  445. if(iFace) {
  446. VecSubf(AdjVertice[1], Vertice[1], u);
  447. VecSubf(Vertice[0], Vertice[1], v);
  448. VecCrossf(v, u, AdjNormal);
  449. // Calculate angle between the Normal vectors
  450. // where:
  451. // u.v = u1v1 + u2v2 + u3v3
  452. // u.v = |u||v|cos theta
  453. // theta = inv cos(u.v/|u||v|)
  454. //
  455. fAngle = Degreesf( acos( (VecDotf(Normal[1], AdjNormal)) / (VecLenf(Normal[1])*VecLenf(AdjNormal)) ));
  456. if(fAngle <= m_fMaxAngle) {
  457. VecAddf(AveNormal, AdjNormal, AveNormal);
  458. ++iNumAveNormals;
  459. }
  460. VecSubf(AdjVertice[2], Vertice[1], u);
  461. VecSubf(AdjVertice[1], Vertice[1], v);
  462. VecCrossf(v, u, AdjNormal);
  463. // Calculate angle between the Normal vectors
  464. fAngle = Degreesf( acos( (VecDotf(Normal[1], AdjNormal)) / (VecLenf(Normal[1])*VecLenf(AdjNormal)) ));
  465. if(fAngle <= m_fMaxAngle) {
  466. VecAddf(AveNormal, AdjNormal, AveNormal);
  467. ++iNumAveNormals;
  468. }
  469. }
  470. VecSubf(Vertice[2], Vertice[1], u);
  471. VecSubf(AdjVertice[2], Vertice[1], v);
  472. VecCrossf(v, u, AdjNormal);
  473. // Calculate angle between the Normal vectors
  474. fAngle = Degreesf( acos( (VecDotf(Normal[1], AdjNormal)) / (VecLenf(Normal[1])*VecLenf(AdjNormal)) ));
  475. if(fAngle <= m_fMaxAngle) {
  476. VecAddf(AveNormal, AdjNormal, AveNormal);
  477. ++iNumAveNormals;
  478. }
  479. // Calculate the average surface normal for face
  480. // vertice '1'
  481. Normal[1][X] = AveNormal[X]/iNumAveNormals;
  482. Normal[1][Y] = AveNormal[Y]/iNumAveNormals;
  483. Normal[1][Z] = AveNormal[Z]/iNumAveNormals;
  484. VecNormalizef(Normal[1]);
  485. ///////////////////////////////////////////////////
  486. // Face Vertice '2' average surface normal:
  487. iNumAveNormals = 0;
  488. VecSubf(Vertice[1], Vertice[2], u);
  489. VecSubf(Vertice[3], Vertice[2], v);
  490. if(!VecLenf(v))
  491. VecSubf(Vertice[0], Vertice[2], v);
  492. VecCrossf(v, u, Normal[2]);
  493. VecCopy3f(Normal[2], AveNormal);
  494. ++iNumAveNormals;
  495. if(iFace<(m_pPointArray->m_iNumPoints-1)) {
  496. VecSubf(AdjVertice[4], Vertice[2], u);
  497. VecSubf(AdjVertice[3], Vertice[2], v);
  498. VecCrossf(v, u, AdjNormal);
  499. // Calculate angle between the Normal vectors
  500. // where:
  501. // u.v = u1v1 + u2v2 + u3v3
  502. // u.v = |u||v|cos theta
  503. // theta = inv cos(u.v/|u||v|)
  504. //
  505. fAngle = Degreesf( acos( (VecDotf(Normal[2], AdjNormal)) / (VecLenf(Normal[2])*VecLenf(AdjNormal)) ));
  506. if(fAngle <= m_fMaxAngle) {
  507. VecAddf(AveNormal, AdjNormal, AveNormal);
  508. ++iNumAveNormals;
  509. }
  510. VecSubf(Vertice[3], Vertice[2], u);
  511. VecSubf(AdjVertice[4], Vertice[2], v);
  512. VecCrossf(v, u, AdjNormal);
  513. // Calculate angle between the Normal vectors
  514. fAngle = Degreesf( acos( (VecDotf(Normal[2], AdjNormal)) / (VecLenf(Normal[2])*VecLenf(AdjNormal)) ));
  515. if(fAngle <= m_fMaxAngle) {
  516. VecAddf(AveNormal, AdjNormal, AveNormal);
  517. ++iNumAveNormals;
  518. }
  519. }
  520. VecSubf(AdjVertice[3], Vertice[2], u);
  521. VecSubf(Vertice[1], Vertice[2], v);
  522. VecCrossf(v, u, AdjNormal);
  523. // Calculate angle between the Normal vectors
  524. fAngle = Degreesf( acos( (VecDotf(Normal[2], AdjNormal)) / (VecLenf(Normal[2])*VecLenf(AdjNormal)) ));
  525. if(fAngle <= m_fMaxAngle) {
  526. VecAddf(AveNormal, AdjNormal, AveNormal);
  527. ++iNumAveNormals;
  528. }
  529. // Calculate the average surface normal for face
  530. // vertice '2'
  531. Normal[2][X] = AveNormal[X]/iNumAveNormals;
  532. Normal[2][Y] = AveNormal[Y]/iNumAveNormals;
  533. Normal[2][Z] = AveNormal[Z]/iNumAveNormals;
  534. VecNormalizef(Normal[2]);
  535. ///////////////////////////////////////////////////
  536. // Face Vertice '3' average surface normal:
  537. iNumAveNormals = 0;
  538. VecSubf(Vertice[2], Vertice[3], u);
  539. if(!VecLenf(u))
  540. VecSubf(Vertice[1], Vertice[3], u);
  541. VecSubf(Vertice[0], Vertice[3], v);
  542. VecCrossf(v, u, Normal[3]);
  543. VecCopy3f(Normal[3], AveNormal);
  544. ++iNumAveNormals;
  545. if(iFace<(m_pPointArray->m_iNumPoints-1)) {
  546. VecSubf(AdjVertice[6], Vertice[3], u);
  547. VecSubf(AdjVertice[5], Vertice[3], v);
  548. VecCrossf(v, u, AdjNormal);
  549. // Calculate angle between the Normal vectors
  550. // where:
  551. // u.v = u1v1 + u2v2 + u3v3
  552. // u.v = |u||v|cos theta
  553. // theta = inv cos(u.v/|u||v|)
  554. //
  555. fAngle = Degreesf( acos( (VecDotf(Normal[3], AdjNormal)) / (VecLenf(Normal[3])*VecLenf(AdjNormal)) ));
  556. if(fAngle <= m_fMaxAngle) {
  557. VecAddf(AveNormal, AdjNormal, AveNormal);
  558. ++iNumAveNormals;
  559. }
  560. VecSubf(AdjVertice[5], Vertice[3], u);
  561. VecSubf(Vertice[2], Vertice[3], v);
  562. VecCrossf(v, u, AdjNormal);
  563. // Calculate angle between the Normal vectors
  564. fAngle = Degreesf( acos( (VecDotf(Normal[3], AdjNormal)) / (VecLenf(Normal[3])*VecLenf(AdjNormal)) ));
  565. if(fAngle <= m_fMaxAngle) {
  566. VecAddf(AveNormal, AdjNormal, AveNormal);
  567. ++iNumAveNormals;
  568. }
  569. }
  570. VecSubf(Vertice[0], Vertice[3], u);
  571. VecSubf(AdjVertice[6], Vertice[3], v);
  572. VecCrossf(v, u, AdjNormal);
  573. // Calculate angle between the Normal vectors
  574. fAngle = Degreesf( acos( (VecDotf(Normal[3], AdjNormal)) / (VecLenf(Normal[3])*VecLenf(AdjNormal)) ));
  575. if(fAngle <= m_fMaxAngle) {
  576. VecAddf(AveNormal, AdjNormal, AveNormal);
  577. ++iNumAveNormals;
  578. }
  579. // Calculate the average surface normal for face
  580. // vertice '3'
  581. Normal[3][X] = AveNormal[X]/iNumAveNormals;
  582. Normal[3][Y] = AveNormal[Y]/iNumAveNormals;
  583. Normal[3][Z] = AveNormal[Z]/iNumAveNormals;
  584. VecNormalizef(Normal[3]);
  585. }