Линии преобразования Java3D

Я разрабатываю небольшое приложение, которое отображает сферы в Java 3D SimpleUniverse, а затем соединяет некоторые сферы линиями. Работает создание сфер, а также создание линий. Проблемы возникают, когда в рецепте задействовано движение. Перемещать сферы довольно просто, используя объекты Transform3D и задавая новые координаты. Но я хочу обновить линии, соединяющие две удаленные сферы, и важно отметить, что обе сферы могли переместиться на произвольное расстояние в любом направлении, а расчеты обновляются десятки раз в секунду, и они продолжают обновляться в течение довольно долгого времени. длительное время (более 5 минут). Есть ли простой способ обновить координаты линии в Java3D (объекты LineArray, которые я использую)? Вот часть кода, над которым я сейчас работаю:

TransformGroup [] segments;

public void createLines(SphereSet sphereSet, BranchGroup branchGroup) {
    segments = new TransformGroup[sphereSet.getEdgeSet().size()]; //Each edge connects two spheres in the sphereSet.
    Point3f [] source_dest = new Point3f[2];
    int lineIndex = 0;
    for (Edge e : sphereSet.getEdgeSet()) {
        segments[lineIndex] = new TransformGroup();
        segments[lineIndex].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
/**
 *  Now create the Point3f pair that represents a segment connecting two spheres.
 */
        source_dest[0] = new Point3f();
        source_dest[1] = new Point3f();
        source_dest[0].setX(e.getSource().getCoordinates()[0]);
        source_dest[0].setY(e.getSource().getCoordinates()[1]);
        source_dest[0].setZ(e.getSource().getCoordinates()[2]);
        source_dest[1].setX(e.getTarget().getCoordinates()[0]);
        source_dest[1].setY(e.getTarget().getCoordinates()[1]);
        source_dest[1].setZ(e.getTarget().getCoordinates()[2]);

        LineArray line = new LineArray(2, LineArray.COORDINATES);
        line.setCoordinates(0, source_dest);

        Appearance lineApp = new Appearance();
        LineAttributes lineAttr = new LineAttributes(2, LineAttributes.PATTERN_SOLID, true);
        lineApp.setLineAttributes(lineAttr);

        Shape3D lineShape = new Shape3D(line, lineApp);
        segments[lineIndex].addChild(lineShape);

        branchGroup.addChild(segments[lineIndex]);

        lineIndex++;
    }
}

//Now, spheres' coordinates are updated... and we need to update lines' coordinates.

public void updateLines(SphereSet sphereSet) {

    int segmentIndex = 0;
    for (Edge e : sphereSet.getEdgeSet()) {
        //MYSTERIOUS CODE GOES HERE
        segmentIndex++;
    }
}

Заранее спасибо. P.S.: Может быть, мне нужно сделать это через матрицу преобразования. В таком случае совет, как его рассчитать, будет очень полезен. Также в таком случае я хотел бы знать, могут ли после произвольного большого количества итераций из-за потери точности концы линий не совпадать с центрами сфер.


person Azurlake    schedule 17.09.2012    source источник


Ответы (1)


1) Создайте класс, производный от javax.media.j3d.Behavior, например:

public class MyBehavior extends Behavior {

    private WakeupCondition wc = new WakeupOnElapsedTime(100); // Every 0.1 sec.

    public void initialize() {

      wakeupOn(wc);
    }

    public void processStimulus(Enumeration criteria) {

      double[] p = { 0, 0, 0 };
      for(int i = 0;i < nLinePoints;i++) {
          line.getCoordinate(i,p);
          p[0] += RandGenerator.randUniform(-0.1,0.1);
          p[1] += RandGenerator.randUniform(-0.1,0.1);
          p[2] += RandGenerator.randUniform(-0.1,0.1);
          line.setCoordinate(i,p);
      }
      wakeupOn(wc);
    }
}

2) В вашем методе createLines() разрешите чтение и запись координат:

line.setCapability(LineArray.ALLOW_COORDINATE_READ);
line.setCapability(LineArray.ALLOW_COORDINATE_WRITE);

3) Прикрепите поведение к графу сцены:

MyBehavior randomEffect = new MyBehavior();
randomEffect.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0,0.0), 100.0));
rootBranchGroup.addChild(randomEffect);

BoundingSphere определяет подпространство, в котором поведение фактически выполняется.

person tnorgd    schedule 19.09.2012
comment
Спасибо. Это действительно больше, чем то, что я искал. Тестирование и работа :) Что действительно помогло мне, так это тот факт, что вы можете напрямую преобразовывать строки без необходимости преобразования контейнера (TransformGroup), в котором они находятся. Установки ALLOW_COORDINATE_READ&WRITE было достаточно, чтобы внести несколько изменений в мой код. Спасибо! - person Azurlake; 19.09.2012