Java Code Examples for com.google.ar.sceneform.math.Vector3#add()

The following examples show how to use com.google.ar.sceneform.math.Vector3#add() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ExtrudedCylinder.java    From sceneform-samples with Apache License 2.0 4 votes vote down vote up
private static void generateVerticesFromPoints(
    Vector3 desiredUp,
    List<Vertex> vertices,
    List<Quaternion> rotations,
    Vector3 firstPoint,
    Vector3 secondPoint,
    float radius) {

  final Vector3 difference = Vector3.subtract(firstPoint, secondPoint);
  Vector3 directionFromTopToBottom = difference.normalized();
  Quaternion rotationFromAToB = Quaternion.lookRotation(directionFromTopToBottom, desiredUp);

  // cosTheta0 provides the angle between the rotations
  if (!rotations.isEmpty()) {
    double cosTheta0 = dot(rotations.get(rotations.size() - 1), rotationFromAToB);
    // Flip end rotation to get shortest path if needed
    if (cosTheta0 < 0.0) {
      rotationFromAToB = negated(rotationFromAToB);
    }
  }
  rotations.add(rotationFromAToB);

  directionFromTopToBottom =
      Quaternion.rotateVector(rotationFromAToB, Vector3.forward()).normalized();
  Vector3 rightDirection =
      Quaternion.rotateVector(rotationFromAToB, Vector3.right()).normalized();
  Vector3 upDirection = Quaternion.rotateVector(rotationFromAToB, Vector3.up()).normalized();
  desiredUp.set(upDirection);

  List<Vertex> bottomVertices = new ArrayList<>();

  final float halfHeight = difference.length() / 2;
  final Vector3 center = Vector3.add(firstPoint, secondPoint).scaled(.5f);

  final float thetaIncrement = (float) (2 * Math.PI) / NUMBER_OF_SIDES;
  float theta = 0;
  float cosTheta = (float) Math.cos(theta);
  float sinTheta = (float) Math.sin(theta);
  float uStep = (float) 1.0 / NUMBER_OF_SIDES;

  // Generate edge vertices along the sides of the cylinder.
  for (int edgeIndex = 0; edgeIndex <= NUMBER_OF_SIDES; edgeIndex++) {
    // Create top edge vertex
    Vector3 topPosition =
        Vector3.add(
            directionFromTopToBottom.scaled(-halfHeight),
            Vector3.add(
                rightDirection.scaled(radius * cosTheta), upDirection.scaled(radius * sinTheta)));
    Vector3 normal =
        Vector3.subtract(topPosition, directionFromTopToBottom.scaled(-halfHeight)).normalized();
    topPosition = Vector3.add(topPosition, center);
    UvCoordinate uvCoordinate = new UvCoordinate(uStep * edgeIndex, 0);

    Vertex vertex =
        Vertex.builder()
            .setPosition(topPosition)
            .setNormal(normal)
            .setUvCoordinate(uvCoordinate)
            .build();
    vertices.add(vertex);

    // Create bottom edge vertex
    Vector3 bottomPosition =
        Vector3.add(
            directionFromTopToBottom.scaled(halfHeight),
            Vector3.add(
                rightDirection.scaled(radius * cosTheta), upDirection.scaled(radius * sinTheta)));
    normal =
        Vector3.subtract(bottomPosition, directionFromTopToBottom.scaled(halfHeight))
            .normalized();
    bottomPosition = Vector3.add(bottomPosition, center);
    float vHeight = halfHeight * 2;
    uvCoordinate = new UvCoordinate(uStep * edgeIndex, vHeight);

    vertex =
        Vertex.builder()
            .setPosition(bottomPosition)
            .setNormal(normal)
            .setUvCoordinate(uvCoordinate)
            .build();
    bottomVertices.add(vertex);

    theta += thetaIncrement;
    cosTheta = (float) Math.cos(theta);
    sinTheta = (float) Math.sin(theta);
  }
  vertices.addAll(bottomVertices);
}
 
Example 2
Source File: ExtrudedCylinder.java    From sceneform-samples with Apache License 2.0 4 votes vote down vote up
private static void updateConnectingPoints(
    List<Vertex> vertices, List<Vector3> points, List<Quaternion> rotations, float radius) {
  // Loop over each segment of cylinder, connecting the ends of this segment to start of the next.
  int currentSegmentVertexIndex = NUMBER_OF_SIDES + 1;
  int nextSegmentVertexIndex = currentSegmentVertexIndex + NUMBER_OF_SIDES + 1;

  for (int segmentIndex = 0; segmentIndex < points.size() - 2; segmentIndex++) {
    Vector3 influencePoint = points.get(segmentIndex + 1);

    Quaternion averagedRotation =
        lerp(rotations.get(segmentIndex), rotations.get(segmentIndex + 1), .5f);
    Vector3 rightDirection =
        Quaternion.rotateVector(averagedRotation, Vector3.right()).normalized();
    Vector3 upDirection = Quaternion.rotateVector(averagedRotation, Vector3.up()).normalized();

    for (int edgeIndex = 0; edgeIndex <= NUMBER_OF_SIDES; edgeIndex++) {
      // Connect bottom vertex of current edge to the top vertex of the edge on next segment.
      float theta = (float) (2 * Math.PI) * edgeIndex / NUMBER_OF_SIDES;
      float cosTheta = (float) Math.cos(theta);
      float sinTheta = (float) Math.sin(theta);

      // Create new position
      Vector3 position =
          Vector3.add(
              rightDirection.scaled(radius * cosTheta), upDirection.scaled(radius * sinTheta));
      Vector3 normal = position.normalized();
      position.set(Vector3.add(position, influencePoint));

      // Update position, UV, and normals of connecting vertices
      int previousSegmentVertexIndex = currentSegmentVertexIndex - NUMBER_OF_SIDES - 1;
      Vertex updatedVertex =
          Vertex.builder()
              .setPosition(position)
              .setNormal(normal)
              .setUvCoordinate(
                  new UvCoordinate(
                      vertices.get(currentSegmentVertexIndex).getUvCoordinate().x,
                      (Vector3.subtract(
                                  position,
                                  vertices.get(previousSegmentVertexIndex).getPosition())
                              .length()
                          + vertices.get(previousSegmentVertexIndex).getUvCoordinate().y)))
              .build();

      vertices.set(currentSegmentVertexIndex, updatedVertex);
      vertices.remove(nextSegmentVertexIndex);
      currentSegmentVertexIndex++;
    }
    currentSegmentVertexIndex = nextSegmentVertexIndex;
    nextSegmentVertexIndex += NUMBER_OF_SIDES + 1;
  }
}
 
Example 3
Source File: LocationNode.java    From ARCore-Location with MIT License 4 votes vote down vote up
@Override
public void onUpdate(FrameTime frameTime) {

    // Typically, getScene() will never return null because onUpdate() is only called when the node
    // is in the scene.
    // However, if onUpdate is called explicitly or if the node is removed from the scene on a
    // different thread during onUpdate, then getScene may be null.


    for (Node n : getChildren()) {
        if (getScene() == null) {
            return;
        }

        Vector3 cameraPosition = getScene().getCamera().getWorldPosition();
        Vector3 nodePosition = n.getWorldPosition();

        // Compute the difference vector between the camera and anchor
        float dx = cameraPosition.x - nodePosition.x;
        float dy = cameraPosition.y - nodePosition.y;
        float dz = cameraPosition.z - nodePosition.z;

        // Compute the straight-line distance.
        double distanceInAR = Math.sqrt(dx * dx + dy * dy + dz * dz);
        setDistanceInAR(distanceInAR);

        if (locationScene.shouldOffsetOverlapping()) {
            if (locationScene.mArSceneView.getScene().overlapTestAll(n).size() > 0) {
                setHeight(getHeight() + 1.2F);
            }
        }

        if (locationScene.shouldRemoveOverlapping()) {
            Ray ray = new Ray();
            ray.setOrigin(cameraPosition);

            float xDelta = (float) (distanceInAR * Math.sin(Math.PI / 15)); //12 degrees
            Vector3 cameraLeft = getScene().getCamera().getLeft().normalized();

            Vector3 left = Vector3.add(nodePosition, cameraLeft.scaled(xDelta));
            Vector3 center = nodePosition;
            Vector3 right = Vector3.add(nodePosition, cameraLeft.scaled(-xDelta));

            boolean isOverlapping = isOverlapping(n, ray, left, cameraPosition)
                    || isOverlapping(n, ray, center, cameraPosition)
                    || isOverlapping(n, ray, right, cameraPosition);

            if (isOverlapping) {
                setEnabled(false);
            } else {
                setEnabled(true);
            }
        }
    }

    if (!locationScene.minimalRefreshing())
        scaleAndRotate();


    if (renderEvent != null) {
        if (this.isTracking() && this.isActive() && this.isEnabled())
            renderEvent.render(this);
    }
}