Android ArCore.Как я могу сделать вращение для некоторого объекта вдоль линии - PullRequest
0 голосов
/ 12 ноября 2018

Я разрабатываю приложение для Android с библиотекой ArCore. Мне нужно сделать две точки, провести линию между ними и установить текстовые метки рядом с каждой линией.

Текстовые метки необходимо поворачивать лицом к камере и располагать вдоль линии.

1) Добавить линию между 2 точками:

AnchorNode previousPoint = /* point 0 */
AnchorNode currentPoint = /* point 1 */

Vector3 previousPosition = previousPoint.getWorldPosition();
Vector3 currentPosition = currentPoint.getWorldPosition();

Quaternion rotation = currentPoint.getWorldRotation();

float[] f1 = new float[]{currentPosition.x, currentPosition.y, currentPosition.z};
float[] f2 = new float[]{rotation.x, rotation.y, rotation.z, rotation.w};

Vector3 difference = Vector3.subtract(previousPosition, currentPosition);
Vector3 directionFromTopToBottom = difference.normalized();
Quaternion rotationFromAToB = Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());

ModelRenderable model = ShapeFactory.makeCube(new Vector3(.0025f, .0025f, difference.length()), Vector3.zero(), /* material */ );

Anchor anchor = getSession().createAnchor(new Pose(f1, f2));

AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(getScene());

Vector3 lineCenter = Vector3.add(previousPosition, currentPosition).scaled(.5f);
Node lineNode = new Node();
lineNode.setParent(anchorNode);
lineNode.setRenderable(model);
lineNode.setWorldPosition(lineCenter);
lineNode.setWorldRotation(rotationFromAToB);
  1. Добавить текстовую метку

    Quaternion cameraRotation = getCamera().getWorldRotation();

    float distance = Vector3.subtract(cameraPosition, lineCenter).length();

    String result = String.format(Locale.ENGLISH, "%.3f", difference.length()) + ".m";

    ViewRenderable textRenderable = mArModelCreator.getTextView();
    ((TextView)textRenderable.getView()
    .findViewById(R.id.textLabel)).setText(result);

    Node textNode = new Node(); 
    textNode.setParent(lineNode);
    textNode.setRenderable(textRenderable); 
    textNode.setWorldScale(new Vector3(1f, 1f, 1f).scaled(distance));
    textNode.setWorldRotation(Quaternion.multiply(rotationFromAToB, cameraRotation));

Но у меня нет правильного результата.

Мои текущие ярлыки:

wrong labels

Что мне нужно:

what i need

Пожалуйста, помогите мне.

1 Ответ

0 голосов
/ 22 ноября 2018

Для решения проблемы я провел линию между векторами по цилиндрам.

private void addLineBetweenPoints(Scene scene, Vector3 from, Vector3 to) {
        // prepare an anchor position
        Quaternion camQ = scene.getCamera().getWorldRotation();
        float[] f1 = new float[]{to.x, to.y, to.z};
        float[] f2 = new float[]{camQ.x, camQ.y, camQ.z, camQ.w};
        Pose anchorPose = new Pose(f1, f2);

        // make an ARCore Anchor
        Anchor anchor = mCallback.getSession().createAnchor(anchorPose);
        // Node that is automatically positioned in world space based on the ARCore Anchor.
        AnchorNode anchorNode = new AnchorNode(anchor);
        anchorNode.setParent(scene);

        // Compute a line's length
        float lineLength = Vector3.subtract(from, to).length();

        // Prepare a color
        Color colorOrange = new Color(android.graphics.Color.parseColor("#ffa71c"));

        // 1. make a material by the color
        MaterialFactory.makeOpaqueWithColor(getContext(), colorOrange)
                .thenAccept(material -> {
                    // 2. make a model by the material
                    ModelRenderable model = ShapeFactory.makeCylinder(0.0025f, lineLength,
                            new Vector3(0f, lineLength / 2, 0f), material);
                    model.setShadowReceiver(false);
                    model.setShadowCaster(false);

                    // 3. make node
                    Node node = new Node();
                    node.setRenderable(model);
                    node.setParent(anchorNode);

                    // 4. set rotation
                    final Vector3 difference = Vector3.subtract(to, from);
                    final Vector3 directionFromTopToBottom = difference.normalized();
                    final Quaternion rotationFromAToB =
                            Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());
                    node.setWorldRotation(Quaternion.multiply(rotationFromAToB,
                            Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90)));
                });
    }

и добавьте TextNode:

public ViewRenderable getTextView() {
        // return current and make new;
        ViewRenderable renderable = mTextView.makeCopy();
        makeTextModel();
        return renderable;
    }

private void makeTextModel() {
        ViewRenderable.builder()
                .setView(LvgApplication.getContext(), R.layout.view_ar_text)
                .build()
                .thenAccept(renderable -> {
                    renderable.setShadowCaster(false);
                    renderable.setShadowReceiver(false);
                    DpToMetersViewSizer viewSizer = new DpToMetersViewSizer(500);
                    renderable.setSizer(viewSizer);
                    renderable.setHorizontalAlignment(ViewRenderable.HorizontalAlignment.CENTER);
                    renderable.setVerticalAlignment(ViewRenderable.VerticalAlignment.CENTER);
                    mTextView = renderable;
                });
    }

private void addTextNodeToLine(Node node, float length) {
        // make model
        String result = String.format(Locale.ENGLISH, "%.3f", length) + ".m";
        ViewRenderable textRenderable = mArModelCreator.getTextView();
        ((TextView) textRenderable.getView().findViewById(R.id.textLabel)).setText(result);

        Node textNode = new Node();
        textNode.setParent(node);
        textNode.setRenderable(textRenderable);
        textNode.setWorldScale(new Vector3(1f, 1f, 1f).scaled(0));

        textNode.setLocalPosition(new Vector3(
                /* x - width from parent (left/right) */ -0.025f,
                /* y - depth from parent (forward/back) */ length / 2,
                /* z - height from parent (top/down) */ -0.002f));

        Quaternion alongLine = Quaternion.axisAngle(new Vector3(0.0f, 0.0f, 1.0f), -90);
        textNode.setLocalRotation(alongLine);
    }
...