Войти
ПрограммированиеФорумГрафика

FBX Animation (4 стр)

Страницы: 1 2 3 4
#45
20:55, 5 июня 2016

> Логика - для каждого кластера (а это видимо косточка) мы находим все точки, на которые он действует и записываем индексы и веса, а потом рассовываем по вершинам.
Osiris, нет, кластер - это не кость. Кластер ссылается на кость, но сам он костью не является, это просто связь кость=>(набор точек + набор весов). Я это к тому, что, скажем, кластер #0 может ссылаться, например, на кость #100500. Кроме того, кластров может быть (и часто так бывает) меньше, чем костей в скелете - например, если к какой-то кости на приязаны вертексы.

Т.е. логика там должна быть примерно такая:
1. берём кластер
2. из него берём кость
3. смотрим какой индекс этой кости будет в нашем массиве костей (он будет не обязательно таким же, как в ФБХ - ведь его ты строишь сам как хочешь)
4. и уже к этому индексу привязываем

Помимо этого я так же не уверен, что приявзки идут именно в "правильном" порядка - т.е. хз идут ли первыми самые важные привязки, я лично сильно в этом сомневаюсь. Потому я, например, сначала строю список всех привязок костей к кадой вершине, а потом беру из них 4 самых "весомых". Так же я отбрасываю слабые првязки (где сила влияния незначительна) и, если привязок получилось меньше 4х, то в конце добиваю копии последней приязки, но с веосм = 0 (что бы лучше с кэшем работало).


#46
22:05, 5 июня 2016

slava_mib
>2. из него берём кость
А код не покажешь, а то я прямо по кластеру матрицу в ID укладываю.

> Помимо этого я так же не уверен, что приявзки идут именно в "правильном"
> порядка - т.е. хз идут ли первыми самые важные привязки, я лично сильно в этом
> сомневаюсь. Потому я, например, сначала строю список всех привязок костей к
> кадой вершине, а потом беру из них 4 самых "весомых".
У меня больше 4-х не было и они вроде отсортированы

#47
0:15, 6 июня 2016

Как-то так:

void ComputeClusterDeformation(const FbxMesh* pMesh, const FbxCluster* pCluster, FbxAMatrix& lClusterRelativeInitPosition)
{
  FbxAMatrix lReferenceGlobalInitPosition;
  FbxAMatrix lClusterGlobalInitPosition;
  FbxAMatrix lReferenceGeometry;
  pCluster->GetTransformMatrix(lReferenceGlobalInitPosition);

  // Multiply lReferenceGlobalInitPosition by Geometric Transformation
  lReferenceGeometry = GetGeometry(pMesh->GetNode());
  lReferenceGlobalInitPosition *= lReferenceGeometry;

  // Get the link initial global position
  pCluster->GetTransformLinkMatrix(lClusterGlobalInitPosition);

  // Compute the initial position of the link relative to the reference.
  lClusterRelativeInitPosition = lClusterGlobalInitPosition.Inverse() * lReferenceGlobalInitPosition;
}

void exportMesh(FbxMesh* mesh)
{
    ........

    FbxSkin *skin = FbxCast<FbxSkin>(def);
    int clusterCount = skin->GetClusterCount();  
    printf("clusters: %d\n", clusterCount);
    for (int i=0; i<clusterCount; i++) // проходим по всем кластерам. кластер - это "приязка кости к группе точек"
    {
      const FbxCluster* cluster = skin->GetCluster(i); // берём кластер
      const FbxNode* linkNode = cluster->GetLink(); // линк - это кость
      const uint32_t boneNumber = getBoneIndex(linkNode->GetName()); // получаем индекс кости в нашем массиве костей
      const int indCount = cluster->GetControlPointIndicesCount(); // количество индексов (каждый индекс - это номер точки в исходой модели, которая привязанная к данной кости
      const FbxCluster::ELinkMode linkMode = cluster->GetLinkMode(); // режим привязки. он должен быть всегда eNormalize
      const int* indices = cluster->GetControlPointIndices(); // индексы контрольных точек (по идее контрольные точки - это вертексы), привязанных к данной кости
      const double* weights = cluster->GetControlPointWeights(); // а это силы првязки (то, насколько сильно кость влияет на вертекс)
      for (int ind=0; ind<indCount; ind++)
      {
        g_boneWeights.push_back( VertexBoneWeight(indices[ind], boneNumber, float(weights[ind])) ); // сохраняем привязку каждого вертекса к каждой кости в массив
      }
      ...................
      FbxAMatrix inverse_bind_pose;
      ComputeClusterDeformation(mesh, cluster, inverse_bind_pose);
      g_inverseBindPose[boneNumber] =  inverse_bind_pose;
      ...................
   }

#48
0:20, 6 июня 2016

P/S getBoneIndex - это моя собственная функция, которая ищет индекс кости (по её имени) в том массиве костей, который я сам составил (он у меня может отличаться от того порядка, в котором они идут в самом FBX)

> У меня больше 4-х не было и они вроде отсортированы
Да вроде как нет.

#49
11:00, 6 июня 2016

slava_mib
> Да вроде как нет.
У меня нулевые веса не ставит в начало, но это меньшая из приятностей)

Страницы: 1 2 3 4
ПрограммированиеФорумГрафика

Тема в архиве.