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

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // 3dObjectCone.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. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. //////////////////////////////////////////////////////////////////
  28. // C3dObjectCone
  29. IMPLEMENT_DYNAMIC(C3dObjectCone, C3dObject)
  30. /////////////////////////////////////////////////////////////////////////////
  31. // C3dObjectCone construction
  32. C3dObjectCone::C3dObjectCone()
  33. {
  34. // Set the attributes to default values..
  35. m_iType = SHAPE_OBJECT;
  36.     m_szName.Format("Cone %u", nConeObjects++);
  37. m_bSolid  = TRUE;
  38. m_bSmooth = TRUE;
  39. m_fHeight = 2.0f;
  40. m_fBaseRadius = 1.0f;
  41. m_iSegments = 40;
  42. // Create our C3dPointArray object
  43. m_pPointArray = new C3dPointArray;
  44. ASSERT(m_pPointArray);
  45. // Create an array of points for our vertices
  46. m_pPointArray->Create(m_iSegments+2);
  47. // Initialize our cubes vertices (points)
  48. InitVertices();
  49. }
  50. /////////////////////////////////////////////////////////////////////////////
  51. // C3dObjectCone Destructor
  52. C3dObjectCone::~C3dObjectCone()
  53. {
  54. // Delete our point array
  55. if(m_pPointArray)
  56. delete m_pPointArray;
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // C3dObjectCone Methods or virtual function implimentation
  60. void C3dObjectCone::AddAttributePage(C3dWorld* pWorld, LPVOID pSht)
  61. {
  62. C3dObjectPropSheet* pSheet = (C3dObjectPropSheet*)pSht;
  63. ASSERT(pSheet);
  64. // Add the page to the property sheet
  65. pSheet->AddPage(&pSheet->m_ConePage);
  66. // Save the address of this object in the page
  67. pSheet->m_ConePage.m_pObject = this;
  68. }
  69. int C3dObjectCone::LoadBitMapImage(CImageList* pList)
  70. {
  71. CBitmap bitmap;
  72. // If the image index has been stored in this object,
  73. // return the index.
  74. if(m_iBMImage > -1)
  75. return m_iBMImage;
  76. // If the image index for this object type has been
  77. // created, store the index for this object and
  78. // return the index.
  79. if( iObjectConeBMImage > -1) {
  80. m_iBMImage = iObjectConeBMImage;
  81. return m_iBMImage;
  82. }
  83. // The image index for this object type has not been
  84. // loaded and the object image index has not been
  85. // stored.
  86. //
  87. // Load the bitmap for the non-selected light
  88. bitmap.LoadBitmap(IDB_OBJECT_CONE);
  89. m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  90. bitmap.DeleteObject();
  91. // Load the bitmap for the non-selected light
  92. bitmap.LoadBitmap(IDB_OBJECT_CONE_SELECTED);
  93. pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  94. bitmap.DeleteObject();
  95. iObjectConeBMImage = m_iBMImage;
  96. return m_iBMImage;
  97. }
  98. void C3dObjectCone::Serialize(CArchive& ar, int iVersion)
  99. {
  100. CString szBuffer;
  101. if (ar.IsStoring())
  102. {
  103. // Save the Object Class header...
  104. szBuffer.Format("n%sC3dObjectCone {n", szIndent);
  105. ar.WriteString(szBuffer);
  106. // Save the this objects' specific data...
  107. szBuffer.Format("%stSolid         < %d >n", szIndent, m_bSolid);
  108. ar.WriteString(szBuffer);
  109. szBuffer.Format("%stHeight        < %f >n", szIndent, m_fHeight);
  110. ar.WriteString(szBuffer);
  111. szBuffer.Format("%stBaseRadius    < %f >n", szIndent, m_fBaseRadius);
  112. ar.WriteString(szBuffer);
  113. szBuffer.Format("%stSmooth        < %d >n", szIndent, m_bSmooth);
  114. ar.WriteString(szBuffer);
  115. szBuffer.Format("%stSegments      < %d >n", szIndent, m_iSegments);
  116. ar.WriteString(szBuffer);
  117. szBuffer.Format("%stSolid Color   < %d >n", szIndent, m_bSolidColor);
  118. ar.WriteString(szBuffer);
  119. szBuffer.Format("%stNum Points    < %d >n", szIndent, m_pPointArray->m_iNumPoints);
  120. ar.WriteString(szBuffer);
  121. m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
  122. // Save the base class object data...
  123. C3dObject::Serialize(ar, iVersion);
  124. szBuffer.Format("%s}n", szIndent); // end of object def
  125. ar.WriteString(szBuffer);
  126. }
  127. else
  128. {
  129. if(iVersion < 102)
  130. // Read the base class object data...
  131. C3dObject::Serialize(ar, iVersion);
  132. // Read the derived class data..
  133. ar.ReadString(szBuffer);
  134. szBuffer.TrimLeft(); // Remove leading white spaces
  135. sscanf(szBuffer, "Solid         < %d >n", &m_bSolid);
  136. ar.ReadString(szBuffer);
  137. szBuffer.TrimLeft();
  138. sscanf(szBuffer, "Height        < %f >n", &m_fHeight);
  139. ar.ReadString(szBuffer);
  140. szBuffer.TrimLeft();
  141. sscanf(szBuffer, "BaseRadius    < %f >n", &m_fBaseRadius);
  142. if(iVersion < 110)
  143. {
  144. // Version 1.1 changed the definition of our member m_iNumMajor to
  145. // m_iSegments and added point manipulation
  146. ar.ReadString(szBuffer);
  147. szBuffer.TrimLeft();
  148. sscanf(szBuffer, "MajorSlices   < %d >n", &m_iSegments);
  149. // Eliminated member m_iNumMinor (minor slices), so 
  150. // just read the string
  151. ar.ReadString(szBuffer);
  152. // Set the cones point array size
  153. if(m_pPointArray->SetArraySize(m_iSegments+2))
  154. return;
  155. // Initialize our point array vertices
  156. InitVertices();
  157. }
  158. else
  159. {
  160. // Version 1.1 added smooth normals
  161. ar.ReadString(szBuffer);
  162. szBuffer.TrimLeft();
  163. sscanf(szBuffer, "Smooth        < %d >n", &m_bSmooth);
  164. ar.ReadString(szBuffer);
  165. szBuffer.TrimLeft();
  166. sscanf(szBuffer, "Segments      < %d >n", &m_iSegments);
  167. if(iVersion > 130)
  168. {
  169. // Version 1.4 added point color capability
  170. ar.ReadString(szBuffer);
  171. szBuffer.TrimLeft();
  172. sscanf(szBuffer, "Solid Color   < %d >n", &m_bSolidColor);
  173. }
  174. ar.ReadString(szBuffer);
  175. szBuffer.TrimLeft();
  176. sscanf(szBuffer, "Num Points    < %d >n", &m_pPointArray->m_iNumPoints);
  177. // Set the cones point array size
  178. if(m_pPointArray->SetArraySize(m_iSegments+2))
  179. return;
  180. // Read the shape vertice, or point data
  181. m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
  182. }
  183. if(iVersion < 102)
  184. // Read all child objects...
  185. LoadChildObjects(ar, iVersion);
  186. else
  187. // Read the base class object data...
  188. C3dObject::Serialize(ar, iVersion);
  189. }
  190. }
  191. void C3dObjectCone::Build(C3dWorld* pWorld, C3dCamera* pCamera)
  192. {
  193. C3dPointArray Normals;
  194. VECTORF Normal;
  195. GLfloat x0, y0, x1, y1;
  196. double a0, a1;
  197. int i;
  198. // Create an array to hold the segment normals
  199. Normals.Create(m_iSegments+4);
  200. // Calculate our smooth face normals
  201. CalNormals(Normals.m_pPoints, m_bSmooth);
  202. // Compile and build the list
  203. glNewList(m_iDisplayLists, GL_COMPILE_AND_EXECUTE);
  204. C3dPoint* pBaseCenter; // Center point of our cones base
  205. C3dPoint* pApex; // Apex of the cone
  206. C3dPoint* pOuterPoint; // Pointer to the first outer point
  207. C3dPoint* pNextPoint; // Pointer to the next outer point
  208. C3dPoint* pNormal; // Pointer to the radial point normals
  209. C3dPoint* pNextNormal; // Pointer to the next point normal
  210. pBaseCenter = &m_pPointArray->m_pPoints[0]; // first point in array
  211. pApex = &m_pPointArray->m_pPoints[1]; // second point in array
  212. pOuterPoint = &m_pPointArray->m_pPoints[2]; // third point in array
  213. pNormal = &Normals.m_pPoints[2]; // third normal in array
  214. // Initialize our disks vertice points
  215. for(i=0; i<m_iSegments; i++)
  216. {
  217. a0 = i * (360/(double)m_iSegments);
  218. x0 = Cosf((GLfloat)a0);
  219. y0 = Sinf((GLfloat)a0);
  220. a1 = (i+1) * (360/(double)m_iSegments);
  221. x1 = Cosf((GLfloat)a1);
  222. y1 = Sinf((GLfloat)a1);
  223. if(i==m_iSegments-1)
  224. {
  225. // First radial point
  226. pNextPoint  = &m_pPointArray->m_pPoints[2];
  227. pNextNormal = &Normals.m_pPoints[2];
  228. }
  229. else
  230. {
  231. // Next radial point
  232. pNextPoint  = &pOuterPoint[i+1];
  233. pNextNormal = &pNormal[i+1];
  234. }
  235. glBegin(GL_TRIANGLES);
  236. // ** Side of the Cone **
  237. // Calculate the normal for the triangle
  238. CalNormalf(pApex->m_fOrigin,
  239.    pNextPoint->m_fOrigin,
  240.    pOuterPoint[i].m_fOrigin,
  241.    Normal);
  242. glNormal3fv(Normal);
  243. glTexCoord2d((i)*(1/(double)m_iSegments), 1);
  244. if(!m_bSolidColor)
  245. glColor4fv(pApex->m_Color.m_fColor);
  246. glVertex3fv(pApex->m_fOrigin);
  247. if(m_bSmooth)
  248. {
  249. glNormal3fv(pNormal[i].m_fOrigin);
  250. glTexCoord2d((i)*(1/(double)m_iSegments), 0);
  251. if(!m_bSolidColor)
  252. glColor4fv(pOuterPoint[i].m_Color.m_fColor);
  253. glVertex3fv(pOuterPoint[i].m_fOrigin);
  254. glNormal3fv(pNextNormal->m_fOrigin);
  255. glTexCoord2d((i+1)*(1/(double)m_iSegments), 0); 
  256. if(!m_bSolidColor)
  257. glColor4fv(pNextPoint->m_Color.m_fColor);
  258. glVertex3fv(pNextPoint->m_fOrigin);
  259. }
  260. else
  261. {
  262. glTexCoord2d((i)*(1/(double)m_iSegments), 0);
  263. if(!m_bSolidColor)
  264. glColor4fv(pOuterPoint[i].m_Color.m_fColor);
  265. glVertex3fv(pOuterPoint[i].m_fOrigin);
  266. glTexCoord2d((i+1)*(1/(double)m_iSegments), 0); 
  267. if(!m_bSolidColor)
  268. glColor4fv(pNextPoint->m_Color.m_fColor);
  269. glVertex3fv(pNextPoint->m_fOrigin);
  270. }
  271. if(m_bSolid)
  272. {
  273. // ** Bottom of the Cone **
  274. // Calculate the normal for the triangle
  275. CalNormalf(pBaseCenter->m_fOrigin,
  276.    pOuterPoint[i].m_fOrigin,
  277.    pNextPoint->m_fOrigin,
  278.    Normal);
  279. glNormal3fv(Normal);
  280. glTexCoord2d(0.5, 0.5);
  281. if(!m_bSolidColor)
  282. glColor4fv(pBaseCenter->m_Color.m_fColor);
  283. glVertex3fv(pBaseCenter->m_fOrigin);
  284. glTexCoord2d((x1*0.5)+0.5, 1-((y1*0.5)+0.5)); 
  285. if(!m_bSolidColor)
  286. glColor4fv(pNextPoint->m_Color.m_fColor);
  287. glVertex3fv(pNextPoint->m_fOrigin);
  288. glTexCoord2d((x0*0.5)+0.5, 1-((y0*0.5)+0.5)); 
  289. if(!m_bSolidColor)
  290. glColor4fv(pOuterPoint[i].m_Color.m_fColor);
  291. glVertex3fv(pOuterPoint[i].m_fOrigin);
  292. }
  293. glEnd();
  294. }
  295. glEndList();
  296. }
  297. /////////////////////////////////////////////////////////////////////////////
  298. // C3dObjectCone Methods or Implementation
  299. void C3dObjectCone::InitVertices()
  300. {
  301. /* We define our cone as follows:
  302.                *p1 (apex)
  303.          p4 ------ p3
  304.           /         
  305.         /             
  306.     p5 |       *p0    | p2
  307.        |              | 
  308.             BASE    / 
  309.                   /  
  310.          p6 ------ pN
  311. */
  312. C3dPoint* pPoint;
  313. int i;
  314. // Resize our array to ensure we have the memory for our points
  315. if(m_pPointArray->SetArraySize(m_iSegments+2))
  316. return; // function failed
  317. // Set the point to the address of the first point
  318. // in the array
  319. pPoint= m_pPointArray->m_pPoints;
  320. // Initialize our disks vertice points
  321. Vec3f(0.0f, 0.0f, -m_fHeight/2, pPoint[0].m_fOrigin); // Set the base center
  322. Vec3f(0.0f, 0.0f,  m_fHeight/2, pPoint[1].m_fOrigin); // Apex
  323. // Now the points about the base radius
  324. for(i=0; i<m_iSegments; i++)
  325. {
  326. double a0  = i * (360/(double)m_iSegments);
  327. double x0 = Cosd(a0);
  328. double y0 = Sind(a0);
  329. pPoint[i+2].m_fOrigin[X] = (GLfloat)(m_fBaseRadius*x0);
  330. pPoint[i+2].m_fOrigin[Y] = (GLfloat)(m_fBaseRadius*y0);
  331. pPoint[i+2].m_fOrigin[Z] = (GLfloat)(-m_fHeight/2);
  332. }
  333. }
  334. void C3dObjectCone::CalNormals(C3dPoint* pNormals, BOOL bSmooth)
  335. {
  336. // Calculate the normals for each point about the sides of 
  337. // the cone.
  338. C3dPointArray FaceNormals;
  339. int i;
  340. // Create a temporary array to store our face normals
  341. FaceNormals.Create(m_iSegments+2);
  342. C3dPoint* pApex   = &m_pPointArray->m_pPoints[1]; // second point in array
  343. C3dPoint* pOuterPoint = &m_pPointArray->m_pPoints[2]; // third point in array
  344. C3dPoint* pNextPoint; // Pointer to the next outer point
  345. C3dPoint* pFaceNormal = &FaceNormals.m_pPoints[2];
  346. // First calculate the normals for each face (triangle) of the cone
  347. // and store them in the FaceNormal array.
  348. for(i=0; i<m_iSegments; i++)
  349. {
  350. if(i==m_iSegments-1)
  351. // First radial point
  352. pNextPoint = &m_pPointArray->m_pPoints[2];
  353. else
  354. // Next radial point
  355. pNextPoint = &pOuterPoint[i+1];
  356. // Calculate the normal for the triangle
  357. CalNormalf(pApex->m_fOrigin,
  358.    pNextPoint->m_fOrigin,
  359.    pOuterPoint[i].m_fOrigin,
  360.    pFaceNormal[i].m_fOrigin);
  361. }
  362. if(bSmooth)
  363. {
  364. // Now that we have the face normals, calculate the 'smooth' point normals
  365. // for each vertice by averaging the adjacent face normals of each vertice.
  366. C3dPoint* PreviousNormal;
  367. for(i=0; i<m_iSegments; i++)
  368. {
  369. if(i==0)
  370. // Last face normal
  371. PreviousNormal = &pFaceNormal[m_iSegments-1];
  372. else
  373. // Previous face normal
  374. PreviousNormal = &pFaceNormal[i-1];
  375. VecAddf(PreviousNormal->m_fOrigin,
  376. pFaceNormal[i].m_fOrigin,
  377. pNormals[i+2].m_fOrigin); // Skip base center and apex
  378. pNormals[i+2].m_fOrigin[X] = pNormals[i+2].m_fOrigin[X]/2;
  379. pNormals[i+2].m_fOrigin[Y] = pNormals[i+2].m_fOrigin[Y]/2;
  380. pNormals[i+2].m_fOrigin[Z] = pNormals[i+2].m_fOrigin[Z]/2;
  381. }
  382. }
  383. else
  384. {
  385. // Just copy the normals
  386. for(i=0; i<=m_iSegments; i++)
  387. VecCopy3f(pFaceNormal[i].m_fOrigin,
  388.   pNormals[i+2].m_fOrigin);
  389. }
  390. }