3dPointArray.cpp
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:10k
源码类别:
OpenGL
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // 3dPointArray.cpp : implementation file
- //
- // glOOP (OpenGL Object Oriented Programming library)
- // Copyright (c) Craig Fahrnbach 1997, 1998
- //
- // OpenGL is a registered trademark of Silicon Graphics
- //
- //
- // This program is provided for educational and personal use only and
- // is provided without guarantee or warrantee expressed or implied.
- //
- // Commercial use is strickly prohibited without written permission
- // from ImageWare Development.
- //
- // This program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "glOOP.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- //////////////////////////////////////////////////////////////////
- // C3dPointArray
- IMPLEMENT_DYNAMIC(C3dPointArray, CObject)
- /////////////////////////////////////////////////////////////////////////////
- // C3dPointArray construction
- C3dPointArray::C3dPointArray()
- {
- // Initialize our data members
- m_hPoints = NULL;
- m_pPoints = NULL;
- m_iNumPoints = 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dPointArray Destructor
- C3dPointArray::~C3dPointArray()
- {
- // Free our points array memory
- if(m_hPoints)
- {
- GlobalUnlock(m_hPoints);
- GlobalFree(m_hPoints);
- m_hPoints = NULL;
- m_pPoints = NULL;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dPointArray function implimentation
- BOOL C3dPointArray::Create(int iNumPoints)
- {
- if(!iNumPoints)
- return -1;
- m_iNumPoints = iNumPoints;
- m_hPoints = GlobalAlloc(GPTR, iNumPoints*sizeof(C3dPoint));
- if(m_hPoints == NULL) {
- AfxMessageBox("Not enought memory to create Point Array!", MB_OK, NULL);
- return(-1);
- }
- m_pPoints = (C3dPoint*)GlobalLock(m_hPoints);
- if(m_pPoints == NULL) {
- AfxMessageBox("Not enought memory to create Point Array!", MB_OK, NULL);
- GlobalFree(m_hPoints);
- m_hPoints = NULL;
- return(-1);
- }
- return 0;
- }
- BOOL C3dPointArray::SetArraySize(int iNumPoints)
- {
- if(!iNumPoints)
- return -1;
- // Unlock the memory handle
- GlobalUnlock(m_hPoints);
- // Reallocate the memory block
- m_hPoints = GlobalReAlloc(m_hPoints, iNumPoints*sizeof(C3dPoint), GMEM_MOVEABLE | GMEM_ZEROINIT);
- if(m_hPoints == NULL) {
- AfxMessageBox("Not enought memory to resize Point Array!", MB_OK, NULL);
- return(-1);
- }
- m_pPoints = (C3dPoint*)GlobalLock(m_hPoints);
- if(m_pPoints == NULL) {
- AfxMessageBox("Not enought memory to resize Point Array!", MB_OK, NULL);
- GlobalFree(m_hPoints);
- m_hPoints = NULL;
- return(-1);
- }
- // Save the number of points in our array
- m_iNumPoints = iNumPoints;
- return 0;
- }
- BOOL C3dPointArray::Add(float x, float y, float z)
- {
- // Unlock the memory handle
- GlobalUnlock(m_hPoints);
- // Reallocate the memory block
- m_hPoints = GlobalReAlloc(m_hPoints, (m_iNumPoints+1)*sizeof(C3dPoint), GMEM_MOVEABLE | GMEM_ZEROINIT);
- if(m_hPoints == NULL) {
- AfxMessageBox("Not enought memory to add Point to Point Array!", MB_OK, NULL);
- return(-1);
- }
- m_pPoints = (C3dPoint*)GlobalLock(m_hPoints);
- if(m_pPoints == NULL) {
- AfxMessageBox("Not enought memory to add Point to Point Array!", MB_OK, NULL);
- GlobalFree(m_hPoints);
- m_hPoints = NULL;
- return(-1);
- }
- // We sucessfully increased the size of the array, so add the point
- m_pPoints[m_iNumPoints].SetOrigin(x, y, z);
- // Increment the number of points in the array
- m_iNumPoints++;
- return 0;
- }
- BOOL C3dPointArray::CopyFromList(C3dPointList* pPointList)
- {
- ASSERT(pPointList);
- if(pPointList->GetCount() > m_iNumPoints)
- return FALSE;
- // Copy the points from the point list to our
- // members point/vertice array
- C3dPoint* pPoint = NULL;
- int iPoint = 0;
- // walk the list
- POSITION Pos = pPointList->GetHeadPosition();
- while (Pos) {
- pPoint = pPointList->GetAt(Pos);
- m_pPoints[iPoint].m_fOrigin[0] = pPoint->m_fOrigin[0];
- m_pPoints[iPoint].m_fOrigin[1] = pPoint->m_fOrigin[1];
- m_pPoints[iPoint].m_fOrigin[2] = pPoint->m_fOrigin[2];
- pPoint = pPointList->GetNext(Pos);
- ++iPoint;
- }
- return 0;
- }
- void C3dPointArray::Display(C3dWorld* pWorld, C3dCamera* pCamera, C3dObject* pObject, float fPointSize, BOOL bConnectPoints){
- GLfloat fPointColor[4] = { 0.0f, 0.6f, 0.2f, 1.0f }; // Dark Green
- GLfloat fSelectedColor[4] = { 0.9f, 0.9f, 0.0f, 1.0f }; // Yellow
- GLfloat fLineColor[4] = { 0.5f, 0.6f, 0.2f, 1.0f }; // Light Green
- GLfloat fLastOrigin[4];
- BOOL bMoreThanOnePoint = FALSE;
- VECTORF CameraPosn, PointPosn, CameraToPoint;
- float distance;
- GLfloat fRadius;
- Matx4x4 ObjXformMatrix;
- float fPointScale = fPointSize/.01f;
- // Transform the camera's origin to world coordinates
- Transformf(pCamera->m_fOrigin, CameraPosn, pCamera->m_dModelViewMatrix);
- // Get the objects transformation matrix. We will use this to
- // transform each point in the array to world coordinates.
- pObject->GetTransformMatrix(ObjXformMatrix);
- // Disable lighting calculations
- glDisable(GL_LIGHTING);
- glLineWidth(2.0f);
- for(int i=0; i<m_iNumPoints; i++)
- {
- // Calculate the points world position
- VecTransformf(m_pPoints[i].m_fOrigin, PointPosn, ObjXformMatrix);
- // Subtract the cameras' world coordinate from the points's
- // world coordinate, then calculate the distance between them.
- VecSubf(CameraPosn, PointPosn, CameraToPoint);
- distance = VecLenf(CameraToPoint);
- // Now that we have the distance between the camera and the point,
- // calculate our points' radius. (We don't want the point to
- // be too small or too large)
- fRadius = distance/fPointScale;
- if(pWorld->m_pSelectedPnt == &m_pPoints[i])
- m_pPoints[i].Display(fRadius, fSelectedColor, TRUE);
- else
- m_pPoints[i].Display(fRadius, fPointColor, TRUE);
- glColor4fv(fLineColor);
- if(bConnectPoints && bMoreThanOnePoint) {
- glBegin(GL_LINES);
- glVertex3fv(fLastOrigin);
- glVertex3fv(m_pPoints[i].m_fOrigin);
- glEnd();
- }
- fLastOrigin[0] = m_pPoints[i].m_fOrigin[0];
- fLastOrigin[1] = m_pPoints[i].m_fOrigin[1];
- fLastOrigin[2] = m_pPoints[i].m_fOrigin[2];
- fLastOrigin[3] = m_pPoints[i].m_fOrigin[3];
- bMoreThanOnePoint = TRUE;
- }
- // Enable lighting calculations
- glEnable(GL_LIGHTING);
- glLineWidth(1.0f);
- }
- C3dPoint* C3dPointArray::Find(C3dCamera* pCamera, C3dObject* pObject,
- float x, float y, float z)
- {
- static C3dPoint* pLastPoint = NULL;
- BOOL bFoundMatch = FALSE;
- Matx4x4 ObjXformMatrix;
- // Get the objects transformation matrix. We will use this to
- // transform each point in the array to world coordinates.
- pObject->GetTransformMatrix(ObjXformMatrix);
- // Search the array of C3dPoints to find a match
- for(int i=0; i<m_iNumPoints; i++)
- {
- if(m_pPoints[i].IsPoint(pCamera, ObjXformMatrix, x, y, z))
- {
- bFoundMatch = TRUE;
- if(&m_pPoints[i] != pLastPoint)
- {
- pLastPoint = &m_pPoints[i];
- return &m_pPoints[i];
- }
- }
- }
- // We found only one point in the array matching the xyz value
- if(bFoundMatch)
- return pLastPoint;
- return NULL;
- }
- void C3dPointArray::GetMinMax(C3dBoundingBox* pBox)
- {
- C3dPoint* pPoint;
- // Set to large positive number
- pBox->m_fMin[X] = (GLfloat)LARGE_NUMBER;
- pBox->m_fMin[Y] = (GLfloat)LARGE_NUMBER;
- pBox->m_fMin[Z] = (GLfloat)LARGE_NUMBER;
- // Set to large negative number
- pBox->m_fMax[X] = -(GLfloat)LARGE_NUMBER;
- pBox->m_fMax[Y] = -(GLfloat)LARGE_NUMBER;
- pBox->m_fMax[Z] = -(GLfloat)LARGE_NUMBER;
- // Search through the array to find the min/max
- // object coordinates
- for(int i=0; i<m_iNumPoints; i++)
- {
- pPoint = &m_pPoints[i];
- if(pPoint->m_fOrigin[X] > pBox->m_fMax[X])
- pBox->m_fMax[X] = pPoint->m_fOrigin[X];
- if(pPoint->m_fOrigin[Y] > pBox->m_fMax[Y])
- pBox->m_fMax[Y] = pPoint->m_fOrigin[Y];
- if(pPoint->m_fOrigin[Z] > pBox->m_fMax[Z])
- pBox->m_fMax[Z] = pPoint->m_fOrigin[Z];
- if(pPoint->m_fOrigin[X] < pBox->m_fMin[X])
- pBox->m_fMin[X] = pPoint->m_fOrigin[X];
- if(pPoint->m_fOrigin[Y] < pBox->m_fMin[Y])
- pBox->m_fMin[Y] = pPoint->m_fOrigin[Y];
- if(pPoint->m_fOrigin[Z] < pBox->m_fMin[Z])
- pBox->m_fMin[Z] = pPoint->m_fOrigin[Z];
- }
- }
- void C3dPointArray::Serialize(CArchive& ar, int iVersion, BOOL bReadColorData)
- {
- CString szBuffer;
- int i;
- if (ar.IsStoring())
- {
- for(i=0; i<m_iNumPoints; i++)
- {
- szBuffer.Format("%stt < %f, %f, %f >n", szIndent, m_pPoints[i].m_fOrigin[0],
- m_pPoints[i].m_fOrigin[1],
- m_pPoints[i].m_fOrigin[2]);
- ar.WriteString(szBuffer);
- }
- if(bReadColorData)
- {
- szBuffer.Format("%st[color]n", szIndent);
- ar.WriteString(szBuffer);
- for(i=0; i<m_iNumPoints; i++)
- {
- szBuffer.Format("%stt < %f, %f, %f, %f >n", szIndent, m_pPoints[i].m_Color.m_fColor[0],
- m_pPoints[i].m_Color.m_fColor[1],
- m_pPoints[i].m_Color.m_fColor[2],
- m_pPoints[i].m_Color.m_fColor[3]);
- ar.WriteString(szBuffer);
- }
- }
- }
- else
- {
- // Read the shape vertice, or point data
- for(i=0; i<m_iNumPoints; i++)
- {
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "< %f, %f, %f >n", &m_pPoints[i].m_fOrigin[X],
- &m_pPoints[i].m_fOrigin[Y],
- &m_pPoints[i].m_fOrigin[Z]);
- }
- if(iVersion > 110 && bReadColorData)
- {
- ar.ReadString(szBuffer); // [color] header
- // Read the shape vertice, or point data
- for(int i=0; i<m_iNumPoints; i++)
- {
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "< %f, %f, %f, %f >n", &m_pPoints[i].m_Color.m_fColor[0],
- &m_pPoints[i].m_Color.m_fColor[1],
- &m_pPoints[i].m_Color.m_fColor[2],
- &m_pPoints[i].m_Color.m_fColor[3]);
- }
- }
- }
- }