MF3DHelper.h
上传用户:qzpk666
上传日期:2022-08-04
资源大小:59k
文件大小:8k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // MF3DHelper.h: interface for the CMF3DHelper class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_MF3DHELPER_H__E4644642_E2CC_4BC1_8F4B_F127D7329F77__INCLUDED_)
  5. #define AFX_MF3DHELPER_H__E4644642_E2CC_4BC1_8F4B_F127D7329F77__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <cmath>
  10. /*
  11. How to use this class(es):
  12. 1. Add a member variable of type CMF3DHelper to your class
  13. 2. At each window resize (or initially) call CMF3DHelper::Initialize function
  14. Parameters: vMin, vMax is a vector representing your entire data range 
  15. bSupportTrackBall: TRUE if you want to use your mouse to control the 3D object
  16. 3. Call RenderPoint() function to get 2D-Screen coordinates from your 3D-point
  17. */
  18. namespace NeHe {
  19. // Code below (Matrix, Vector) was originally taken from NeHe-SDK, drilled down a little bit
  20. // ------ BEGIN OF NeHe specific class ------------
  21. //  http://nehe.gamedev.net/
  22. // Nehe SDK
  23. //  Copyright 2002 Jeff Molofee, Gregory Austwick and Others
  24. class Point {
  25. public:
  26. Point (float xx, float yy) { x=xx; y=yy; }
  27. Point() { x = y = 0.0f; }
  28. float x;
  29. float y;
  30. };
  31. typedef struct VECTOR3D {
  32. float x;
  33. float y;
  34. float z;
  35. } VECTOR3D, *PVECTOR3D;
  36. typedef struct VECTOR4D {
  37. float x;
  38. float y;
  39. float z;
  40. float w;
  41. } VECTOR4D, *PVECTOR4D;
  42. #define SQR(x) ((x)*(x))
  43. class Vector {
  44. public:
  45. float x,y,z,w;
  46. Vector() { x=y=z=w=0.0f; }; // clearing constructor
  47. Vector(float vx,float vy,float vz,float vw) { x=vx; y=vy; z=vz; w=vw; };
  48. Vector(float vx,float vy,float vz) { x=vx; y=vy; z=vz; w=1.0f; };
  49. Vector(const Vector &v) { x=v.x; y=v.y; z=v.z; w=v.w; };
  50. Vector operator + (Vector &v) { return Vector((x+v.x),(y+v.y),(z+v.z),(w+v.w)); };
  51. Vector operator - (Vector &v) { return Vector((x-v.x),(y-v.y),(z-v.z),(w-v.w)); };
  52. Vector operator * (Vector &v) { return Vector((x*v.x),(y*v.y),(z*v.z),(w*v.w)); };
  53. Vector operator * (float f) { return Vector((x*f),(y*f),(z*f),(w*f)); };
  54. // assignment arithmetic operators
  55. Vector operator += (Vector &v) {x+=v.x; y+=v.y; z+=v.z; w+=v.w; return *this;}
  56. Vector operator -= (Vector &v) {x-=v.x; y-=v.y; z-=v.z; w-=v.w; return *this;}
  57. Vector operator *= (Vector &v) {x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this;}
  58. Vector operator *= (float f) {x*=f; y*=f; z*=f; w*=f; return *this;}
  59. Vector operator /= (float f) {x/=f; y/=f; z/=f; w/=f; return *this;}
  60. // Vector functions
  61. void Null() { x = y = z = w = 0.0f; }
  62. // Magnitude function
  63. float Mag() { return (float)sqrt(SQR(x)+SQR(y)+SQR(z)+SQR(w)); };
  64. float Mag3() { return (float)sqrt(SQR(x)+SQR(y)+SQR(z)); };
  65. // Magnitude squared
  66. float MagSqr() { return (SQR(x)+SQR(y)+SQR(z)+SQR(w)); };
  67. float MagSqr3() { return (SQR(x)+SQR(y)+SQR(z)); };
  68. // Normalize vector
  69. void Normalize() { float mag=this->Mag(); x/=mag; y/=mag; z/=mag; w/=mag; };
  70. void Normalize3() { float mag=this->Mag3(); x/=mag; y/=mag; z/=mag; };
  71. // Dot product
  72. float Dot(Vector &v) { return (((x*v.x)+(y*v.y)+(z*v.z)+(w*v.w))/(this->Mag()*v.Mag())); };
  73. float Dot3(Vector &v) { return (((x*v.x)+(y*v.y)+(z*v.z))/(this->Mag3()*v.Mag3())); };
  74. float Length() { return MagSqr(); }
  75. float Length3() { return MagSqr3(); }
  76. // Cross product
  77. Vector Cross(Vector &v) { return Vector( (y*v.z)-(z*v.y) , (z*v.x)-(x*v.z) , (x*v.y)-(y*v.x) ); };
  78. void Trace() { TRACE(_T("Vector<%.2f / %.2f / %.2f / %.2f>"), x,y,z,w); }
  79. };
  80. #define Idx(x,y) ((x*4)+y)
  81. class Matrix {
  82. public:
  83. float m[16];
  84. Matrix() { this->Id(); };
  85. Matrix(const Matrix &mt) { for (int ct=0; ct<16; ct++) m[ct]=mt.m[ct]; };
  86. // Zero matrix
  87. void Zero() { for (int ct=0; ct<16; ct++) m[ct]=0.0f; };
  88. // Identity matrix
  89. void Id() { this->Zero(); m[0]=1.0f; m[5]=1.0f; m[10]=1.0f; m[15]=1.0f;  };
  90. // Multiply matrix
  91. Matrix operator * (Matrix &mt) {
  92. Matrix temp; // the return matrix
  93. for (int cty=0; cty<4; cty++) {
  94. float row1=m[Idx(0,cty)],row2=m[Idx(1,cty)],row3=m[Idx(2,cty)],row4=m[Idx(3,cty)];
  95. for (int ctx=0; ctx<4; ctx++) {
  96. temp.m[Idx(ctx,cty)]=(row1*mt.m[Idx(ctx,0)])+(row2*mt.m[Idx(ctx,1)])+
  97. (row3*mt.m[Idx(ctx,2)])+(row4*mt.m[Idx(ctx,3)]);
  98. }
  99. }
  100. return temp;
  101. };
  102. // Multiply matrix and assign
  103. Matrix operator *= (Matrix &mt) {
  104. Matrix temp; // the return matrix
  105. for (int cty=0; cty<4; cty++) {
  106. // get the present row
  107. float row1=m[Idx(0,cty)],row2=m[Idx(1,cty)],row3=m[Idx(2,cty)],row4=m[Idx(3,cty)];
  108. // then xs
  109. for (int ctx=0; ctx<4; ctx++) {
  110. temp.m[Idx(ctx,cty)]=(row1*mt.m[Idx(ctx,0)])+(row2*mt.m[Idx(ctx,1)])+
  111. (row3*mt.m[Idx(ctx,2)])+(row4*mt.m[Idx(ctx,3)]);
  112. }
  113. }
  114. // copy back to ours
  115. for (int ct=0; ct<16; ct++) m[ct]=temp.m[ct];
  116. return *this;
  117. };
  118. // Transform a vector by the matrix
  119. Vector operator * (Vector &v) {
  120. Vector temp; // the return vector
  121. temp.x=v.x*m[Idx(0,0)]+v.y*m[Idx(0,1)]+v.z*m[Idx(0,2)]+v.w*m[Idx(0,3)];
  122. temp.y=v.x*m[Idx(1,0)]+v.y*m[Idx(1,1)]+v.z*m[Idx(1,2)]+v.w*m[Idx(1,3)];
  123. temp.z=v.x*m[Idx(2,0)]+v.y*m[Idx(2,1)]+v.z*m[Idx(2,2)]+v.w*m[Idx(2,3)];
  124. temp.w=v.x*m[Idx(3,0)]+v.y*m[Idx(3,1)]+v.z*m[Idx(3,2)]+v.w*m[Idx(3,3)];
  125. return Vector(temp);
  126. };
  127. };
  128. // CMFArcBall: Class to allow user to rotate view-port
  129. // Pressing <CTRL> allows user to rotate about Z-axis
  130. class CMFArcBall {
  131. public:
  132. CMFArcBall ();
  133. virtual ~CMFArcBall();
  134. void Initialize(int iWidth, int iHeight) { 
  135. m_iWidth = iWidth; 
  136. m_iHeight = iHeight; 
  137. m_fXRotation = m_fYRotation = m_fZRotation = 0.0f; 
  138. m_bLButtonDown = FALSE; 
  139. m_fXDiv = (float)m_iWidth / (360.0f/2.0f); // whole window covers 180 degree
  140. m_fYDiv = (float)m_iHeight / (360.0f/2.0f);
  141. }
  142. void SetRotation(float fXRot, float fYRot, float fZRot) {
  143. m_fXRotation = fXRot;
  144. m_fYRotation = fYRot;
  145. m_fZRotation = fZRot;
  146. }
  147. BOOL Update(CDC* pDC, NeHe::Vector &cRotationDelta, NeHe::Vector &cRotationCumulative);
  148. protected:
  149. BOOL getMousePosition(BOOL &bLDown, BOOL &bLToggled, BOOL &bRDown, BOOL &bRToggled, int &xPos, int &yPos, CDC* pDC);
  150. private:
  151. void mouseToArc(CPoint cPt, float &fx, float &fy) ;
  152. private:
  153. CPoint m_cMousePoint;
  154. BOOL m_bLButtonDown;
  155. float m_fXRotation;
  156. float m_fYRotation;
  157. float m_fZRotation;
  158. int m_iWidth;
  159. int m_iHeight;
  160. float m_fXDiv;
  161. float m_fYDiv;
  162. };
  163. }; // namespace NeHe
  164. class CMF3DHelper {
  165. public:
  166.     CMF3DHelper();
  167.     virtual ~CMF3DHelper();
  168. // Call this function (after initialization) to get 2D-screen-coordinates from your 3D point
  169. /* Remark: Vector needs to be normalized to -1..1! */
  170.     NeHe::Vector RenderPoint(NeHe::Vector v3DPoint);
  171. // Draws the cube representing your 3D-environment
  172.     void DrawVisibilityCube(CDC* pDC, BOOL bDrawAxes=TRUE, BOOL bDrawBoundingCoordinates=FALSE);
  173.     // Re-Initialize the 3D-environment
  174.     BOOL Initialize(CDC *pTargetDC, NeHe::Vector vMin, NeHe::Vector vMax, BOOL bSupportTrackBall);
  175. BOOL Reset(CDC *pTargetDC, NeHe::Vector vMin, NeHe::Vector vMax, BOOL bSupportTrackBall);
  176. // Needs to be called cyclically, updates the 3D-environment according to mouse position
  177. void UpdateTrackBall(CDC *pDC);
  178. public:
  179. // Operations to modify viewport, mostly unused (internally only)
  180.     void Rotate(float angleX,float angleY,float angleZ, BOOL bAbsolute);
  181. void Scale(float xFactor,float yFactor,float zFactor);
  182.     void Translate(float x,float y,float z);
  183. void RotateVector(float fAngle,float fVectorX,float fVectorY, float fVectorZ, BOOL bAbsolute);
  184. private:
  185.     float cotangens(float x);
  186.     BOOL setupPerspective(float fovy, float aspect, float zNear, float zFar);
  187.     void emul_glLoadIdentity();
  188.     BOOL emul_gluPerspective(float fovy, float aspect, float zNear, float zFar);
  189.     void emul_glViewport(int x, int y, int widht, int height);
  190.     void emul_glRotatef(float angle,float x,float y, float z);
  191.     void emul_glTranslatef(float x, float y, float z);
  192. void emul_glScalef(float x, float y, float z); 
  193. private:
  194.     NeHe::Matrix m_mProjection;
  195.     NeHe::Matrix m_mRotation;
  196. NeHe::Matrix m_mModel;
  197.     float m_fViewport_x;
  198.     float m_fViewport_y;
  199.     float m_fViewport_widht;
  200.     float m_fViewport_height;
  201.     NeHe::Vector m_vCubeMin;
  202.     NeHe::Vector m_vCubeMax;
  203. // Try to speed up things a little bit...
  204. NeHe::Matrix m_mShadow;
  205. BOOL m_bShadowUpdateRequired;
  206. NeHe::CMFArcBall m_cTrackBall;
  207. };
  208. #endif // !defined(AFX_MF3DHELPER_H__E4644642_E2CC_4BC1_8F4B_F127D7329F77__INCLUDED_)