Android ArCore. 如何使某个物体沿一条直线旋转?

3

我正在使用ArCore库开发Android应用程序。我需要实现以下两点需求:在两点之间绘制一条直线,并在每条线附近设置文本标签。

文本标签需要面向相机旋转并沿着该线设置位置。

1)添加连接两个点的直线:

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个回答

1
为了解决这个问题,我已经通过圆柱体在向量之间画了一条线。
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);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接