Re[3]: вопрос к архитектуре 3D приложения
От: Eugene Kilachkoff Россия  
Дата: 04.07.06 11:30
Оценка:
Здравствуйте, Zubkin, Вы писали:

Z>Здравствуйте, Eugene Kilachkoff, Вы писали:


Z>>>вопрос:

Z>>>как "должна" выглядеть архитектура такого приложения?
EK>>Ну, обычно в 3D выделяют несколько общеупотребительных примитивов:

Z>благодарю за ответ.


Z>если я правильно понял,

Z>я должен создать классы для этих общеупотребительных примитивов,
Ну примерно. Типа далее псевдокод.
class Vector { float x,y,z; }
class Face { int idx1,idx2,idx3; }
class Mesh { Vector[] vertices; Face[] faces; }
// ну и так далее


Z>каждый описывает своё состояние (вращение, scale и т.д.),

Немного не так.
class Matrix
{
  float[4][4] data;
  static Matrix buildI()
  {
    return ( [ 1  0  0  0 ],
             [ 0  1  0  0 ],
             [ 0  0  1  0 ],
             [ 0  0  0  1 ] );
  }

  static Matrix buildT(Vector v)
  {
    return ( [ 0  0  0  v.x ],
             [ 0  0  0  v.y ],
             [ 0  0  0  v.z ],
             [ 0  0  0  1   ] );
  }

  // далее как в учебнике
  static Matrix buildRotX(float angle) ...
  static Matrix buildRotY(float angle) ...  
  static Matrix buildRotZ(float angle) ...  
}

class TransformationStack
{
    Matrix[] transformations;
    void push(Matrix m) { transformations.append(m); }
    Matrix collapse()
    {
       Matrix r = Matrix.buildI();
       foreach(m in transformations) r = m * r;
       // вообще, справа или слева умножать зависит от того, в каком порядке хранятся матрицы в стеке
       // и от представления векторов.
       // обычно предполагается что используются вектор-столбцы и они умножаются на матрицу справа
       // соответственно, для набора преобразований "R: поворот на 30", затем "T: перенос в (1,0,0)"
       // результирующий вектор должен получаться как Vr = T * R * v
       return r;
    }
}

class Object3D
{
  Mesh[] meshes;
  TransformationStack tstack;
  String name;
}

Можно еще использовать представление вращения в виде кватернионов (google for quaternion rotation).

Z>все объекты храняться в одной структуре,

Z>потом есть Scenegraph который регуларно проходит по структуре
Scenegraph -- это и есть структура.
class SceneGraph
{
  class Group { WeakReference<Object3D>[] members; }
  class TreeNode { WeakRefernce<Object3D> object; TreeNode parent; TreeNode[] child; }

  Object3D[] objectPool; // хранилище всех объектов, чтобы не бегать долго по деревьям
  Group[] groupList; // логическая группировка (ex: голова -- это глаза, плюс уши, плюс зубы и так далее)
  TreeNode[] kinematicTreeRoots; // лес деревьев подчинения объектов для прямой (forward) кинематики
  // (если потянуть за туловище, голова, руки и ноги потянутся за ним.
  // НО, если потянуть за ногу, все остальное останется на месте, для этого нужна уже inverse kinematics

  void drawAll()
  {
     foreach(node in kinematicTreeRoots) drawRecursive(node,Matrix.buildI());
     // те, которые сами по себе. Хотя для них лучше ввести отдельный root.
     foreach(obj in objectPool)
       if wasNotDrawnInPreviousStep(obj) drawObject(obj);
  }

  void drawRecursive(TreeNode node,Matrix parentTransform)
  {
     foreach(n in node.child) drawRecursive(n,n.object.tstack.collapse());
     Matrix myTransform = node.object.tstack.collapse() * parentTransform; // watch the order !
     Mesh m = transformMesh(node.object.mesh, myTransform);
     drawMesh(m);         
  }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.