⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cloth.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            m_Points[i].m_vecVelocity -= vecDist;
          }
        }

        // Check if point collides with a plane object
        if(pObject->m_Type == COLLISION_PLANE) {

          // Put plane in a local variable
          D3DXPLANE Plane = pObject->m_Plane;

          // Transform plane if needed
          if(matTransform) {

            // Inverse and transpose the transformation
            // but do it only once to save time
            if(MatrixInversedAndTransposed == FALSE) {
              MatrixInversedAndTransposed = TRUE;
              D3DXMatrixInverse(&matITTransform, NULL, matTransform);
              D3DXMatrixTranspose(&matITTransform, &matITTransform);
            }

            // Transform the plane
            D3DXPlaneTransform(&Plane, &Plane, &matITTransform);
          } 

          // Get the normal vector
          D3DXVECTOR3 vecNormal = D3DXVECTOR3(Plane.a,        \
                                              Plane.b,        \
                                              Plane.c);

          // Get the dot product between the plane's normal
          // and the point's position
          float Dot = D3DXVec3Dot(&m_Points[i].m_vecPos,      \
                                  &vecNormal) + Plane.d;

          // Check if point is behind plane
          if(Dot < 0.0f) {

            // Scale the plane's normal by the 
            // absolute dot product.
            vecNormal *= (-Dot);

            // Move point and adjust velocity by normal vector
            m_Points[i].m_vecPos      += vecNormal;
            m_Points[i].m_vecVelocity += vecNormal;
          }
        }

        // Go to next collision object
        pObject = pObject->m_Next;
      }
    }
  }
}

void cClothMesh::RebuildMesh(ID3DXMesh *Mesh)
{
  DWORD i;

  // Error checking
  if(!m_NumPoints || !m_Points || !Mesh)
    return;

  // Lock vertex buffer
  char *Vertices;
  Mesh->LockVertexBuffer(0, (void**)&Vertices);

  // Store each point in list
  for(i=0;i<m_NumPoints;i++) {

    // Get pointer to vertex data in buffer
    sClothVertexPos *Vertex = (sClothVertexPos*)Vertices;
    
    // Store vertex coordinates
    Vertex->vecPos = m_Points[i].m_vecPos;

    // Go to next vertex
    Vertices += m_VertexStride;
  }

  // Unlock vertex buffer
  Mesh->UnlockVertexBuffer();

  // Recompute normals
  D3DXComputeNormals(Mesh, NULL);
}

BOOL cClothMesh::Create(ID3DXMesh *Mesh, char *PointSpringXFile)
{
  DWORD i;

  // Free a prior mesh
  Free();

  // Error checking
  if(!Mesh)
    return FALSE;

  // Calculate vertex pitch (size of vertex data)
  m_VertexStride = D3DXGetFVFVertexSize(Mesh->GetFVF());

  ////////////////////////////////////////////////////////////
  // Calculate the spring information from the loaded mesh
  ////////////////////////////////////////////////////////////

  // Get the # of faces and allocate array
  m_NumFaces = Mesh->GetNumFaces();
  m_Faces = new DWORD[m_NumFaces*3];

  // Lock index buffer and copy over data (16-bit indices)
  unsigned short *Indices;
  Mesh->LockIndexBuffer(0, (void**)&Indices);
  for(i=0;i<m_NumFaces*3;i++)
    m_Faces[i] = (DWORD)*Indices++;
  Mesh->UnlockIndexBuffer();

  // Get the # of points in mesh and allocate structures
  m_NumPoints = Mesh->GetNumVertices();
  m_Points = new cClothPoint[m_NumPoints]();

  // Lock vertex buffer and stuff data into cloth points
  char *Vertices;
  Mesh->LockVertexBuffer(0, (void**)&Vertices);
  for(i=0;i<m_NumPoints;i++) {

    // Get pointer to vertex coordinates
    sClothVertexPos *Vertex = (sClothVertexPos*)Vertices;

    // Store position, velocity, force, and mass
    m_Points[i].m_vecOriginalPos = Vertex->vecPos;
    m_Points[i].m_vecPos      = m_Points[i].m_vecOriginalPos;
    m_Points[i].m_Mass        = 1.0f;
    m_Points[i].m_OneOverMass = 1.0f;

    // Setup point's states
    m_Points[i].m_vecVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    m_Points[i].m_vecForce =    D3DXVECTOR3(0.0f, 0.0f, 0.0f);

    // Go to next vertex
    Vertices += m_VertexStride;
  }
  Mesh->UnlockVertexBuffer();

  // Build list of springs from face vertices
  for(i=0;i<m_NumFaces;i++) {

    // Get vertices that construct a face
    DWORD Vertex1 = m_Faces[i*3];
    DWORD Vertex2 = m_Faces[i*3+1];
    DWORD Vertex3 = m_Faces[i*3+2];

    // Add springs from 1->2, 2->3, and 3->1
    AddSpring(Vertex1, Vertex2);
    AddSpring(Vertex2, Vertex3);
    AddSpring(Vertex3, Vertex1);
  }

  // Parse cloth masses and springs from file
  if(PointSpringXFile)
    Parse(PointSpringXFile);

  return TRUE;
}

void cClothMesh::Free()
{
  m_NumPoints = 0;     // Delete cloth points array
  delete [] m_Points;
  m_Points = NULL;
  
  m_NumSprings = 0;    // Delete spring linked list
  delete m_Springs;
  m_Springs = NULL;

  m_NumFaces = 0;      // Delete faces array
  delete [] m_Faces;
  m_Faces = NULL;

  m_VertexStride = 0;   // Reset values
}

void cClothMesh::Reset()
{
  // Error checking
  if(!m_NumPoints || !m_Points)
    return;

  // Go through each point
  for(DWORD i=0;i<m_NumPoints;i++) {

    // Copy original points
    m_Points[i].m_vecPos = m_Points[i].m_vecOriginalPos;

    // Clear forces
    m_Points[i].m_vecVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  }
}

void cClothMesh::AddSpring(DWORD Point1, DWORD Point2, float Ks, float Kd)
{
  cClothSpring *Spring = m_Springs;

  // Don't add springs that share the same point
  if(Point1 == Point2)
    return;

  // Search for a duplicate spring already in list
  while(Spring != NULL) {

    // Check if a match and return if so (no duplicates)
    if(Point1 == Spring->m_Point1 && Point2 == Spring->m_Point2)
      return;
    if(Point1 == Spring->m_Point2 && Point2 == Spring->m_Point1)
      return;

    // Make sure the two points are not the same
    if(Point1 == Point2)
      return;

    // Go to next spring
    Spring = Spring->m_Next;
  }

  // Allocate a spring and link to list (increasing count)
  Spring = new cClothSpring();
  Spring->m_Next = m_Springs;
  m_Springs = Spring;
  m_NumSprings++;

  // Set spring's data
  Spring->m_Point1 = Point1;
  Spring->m_Point2 = Point2;
  Spring->m_Ks     = Ks;
  Spring->m_Kd     = Kd;

  // Calculate resting length of spring
  D3DXVECTOR3 vecDist = m_Points[Point2].m_vecPos - 
                        m_Points[Point1].m_vecPos;
  Spring->m_RestingLength = D3DXVec3Length(&vecDist);
}

void cClothMesh::SetMass(DWORD Point, float Mass)
{
  // Only set mass if it's a valid point value
  if(Point < m_NumPoints) {
    m_Points[Point].m_Mass = Mass;
    m_Points[Point].m_OneOverMass = (Mass==0.0f)?0.0f:1.0f/Mass;
  }
}

DWORD cClothMesh::GetNumPoints()
{
  return m_NumPoints;
}

cClothPoint *cClothMesh::GetPoints()
{
  return m_Points;
}

DWORD cClothMesh::GetNumSprings()
{
  return m_NumSprings;
}

cClothSpring *cClothMesh::GetSprings()
{
  return m_Springs;
}

DWORD cClothMesh::GetNumFaces()
{
  return m_NumFaces;
}

DWORD *cClothMesh::GetFaces()
{
  return m_Faces;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -