pointerMove method

void pointerMove(
  1. Pointer pointer
)

Implementation

void pointerMove(Pointer pointer) {
  if (pointer.x == _pointer0?.x &&
      pointer.y == _pointer0?.y &&
      pointer.button == _pointer0?.button) {
    return;
  }
  _pointer0 = pointer;

  final axis = this.axis;
  final GizmoType mode = this.mode;
  final object = this.object;
  String space = this.space;

  if (mode == GizmoType.scale) {
    space = 'local';
  }
  else if (axis == 'E' || axis == 'XYZE' || axis == 'XYZ') {
    space = 'world';
  }

  if (object == null ||
      axis == null ||
      dragging == false ||
      pointer.button != 0) return;

  _raycaster.setFromCamera(Vector2(pointer.x, pointer.y), camera!);

  final planeIntersect = intersectObjectWithRay(_plane, _raycaster, true);

  if (planeIntersect == null) return;

  pointEnd.setFrom(planeIntersect.point!).sub(worldPositionStart);

  if (mode == GizmoType.translate) {
    // Apply translate

    _offset.setFrom(pointEnd).sub(pointStart);

    if (space == 'local' && axis != 'XYZ') {
      _offset.applyQuaternion(_worldQuaternionInv);
    }

    if (!axis.contains('X')) _offset.x = 0;
    if (!axis.contains('Y')) _offset.y = 0;
    if (!axis.contains('Z')) _offset.z = 0;

    if (space == 'local' && axis != 'XYZ') {
      _offset.applyQuaternion(_quaternionStart).divide(_parentScale);
    }
    else {
      _offset.applyQuaternion(_parentQuaternionInv).divide(_parentScale);
    }

    object.position.setFrom(_offset).add(_positionStart);

    // Apply translation snap

    if (translationSnap != null) {
      if (space == 'local') {
        object.position.applyQuaternion(
            _tempQuaternion.setFrom(_quaternionStart).invert());

        if (axis.contains('X')) {
          object.position.x = (object.position.x / translationSnap!).round() * translationSnap!;
        }

        if (axis.contains('Y')) {
          object.position.y = (object.position.y / translationSnap!).round() * translationSnap!;
        }

        if (axis.contains('Z')) {
          object.position.z = (object.position.z / translationSnap!).round() * translationSnap!;
        }

        object.position.applyQuaternion(_quaternionStart);
      }

      if (space == 'world') {
        if (object.parent != null) {
          //final _vec = _tempVector.setFromMatrixPosition(object.parent?.matrixWorld);
          object.position.add(_tempVector.setFromMatrixPosition(object.parent?.matrixWorld));
        }

        if (axis.contains('X')) {
          object.position.x = (object.position.x / translationSnap!).round() * translationSnap!;
        }

        if (axis.contains('Y')) {
          object.position.y = (object.position.y / translationSnap!).round() * translationSnap!;
        }

        if (axis.contains('Z')) {
          object.position.z = (object.position.z / translationSnap!).round() * translationSnap!;
        }

        if (object.parent != null) {
          object.position.sub(
              _tempVector.setFromMatrixPosition(object.parent?.matrixWorld));
        }
      }
    }
  }
  else if (mode == GizmoType.scale) {
    if (axis.contains('XYZ')) {
      double d = pointEnd.length / pointStart.length;

      if (pointEnd.dot(pointStart) < 0){
        d *= -1;
      }

      _tempVector2.setValues(d, d, d);
    }
    else {
      _tempVector.setFrom(pointStart);
      _tempVector2.setFrom(pointEnd);

      _tempVector.applyQuaternion(_worldQuaternionInv);
      _tempVector2.applyQuaternion(_worldQuaternionInv);

      _tempVector2.divide(_tempVector);

      if (!axis.contains('X')) {
        _tempVector2.x = 1;
      }

      if (!axis.contains('Y')) {
        _tempVector2.y = 1;
      }

      if (!axis.contains('Z')) {
        _tempVector2.z = 1;
      }
    }

    // Apply scale
    object.scale.setFrom(_scaleStart).multiply(_tempVector2);

    if (scaleSnap != null) {
      if (axis.contains('X')) {
        double x_ = (object.scale.x / scaleSnap!).round() * scaleSnap!;
        object.scale.x = x_ != 0 ? x_ : scaleSnap!;
      }

      if (axis.contains('Y')) {
        double y_ = (object.scale.y / scaleSnap!).round() * scaleSnap!;
        object.scale.y = y_ != 0 ? y_ : scaleSnap!;
      }

      if (axis.contains('Z')) {
        double z_ = (object.scale.z / scaleSnap!).round() * scaleSnap!;
        object.scale.z = z_ != 0 ? z_ : scaleSnap!;
      }
    }
  }
  else if (mode == GizmoType.rotate) {
    _offset.setFrom(pointEnd).sub(pointStart);

    final rotationSpeed = 20 / worldPosition.distanceTo(
            _tempVector.setFromMatrixPosition(camera?.matrixWorld));

    if (axis == 'E') {
      rotationAxis.setFrom(eye);
      rotationAngle = pointEnd.angleTo(pointStart);

      _startNorm.setFrom(pointStart).normalize();
      _endNorm.setFrom(pointEnd).normalize();

      rotationAngle *=
          (_endNorm.cross(_startNorm).dot(eye) < 0 ? 1 : -1);
    }
    else if (axis == 'XYZE') {
      rotationAxis.setFrom(_offset).cross(eye).normalize();
      rotationAngle = _offset.dot(_tempVector.setFrom(rotationAxis).cross(eye)) * rotationSpeed;
    }
    else if (axis == 'X' || axis == 'Y' || axis == 'Z') {
      rotationAxis.setFrom(_unit[axis]!);

      _tempVector.setFrom(_unit[axis]!);

      if (space == 'local') {
        _tempVector.applyQuaternion(worldQuaternion);
      }

      rotationAngle = _offset.dot(_tempVector.cross(eye).normalize()) * rotationSpeed;
    }

    // Apply rotation snap

    if (rotationSnap != null){
      rotationAngle = (rotationAngle / rotationSnap!).roundToDouble() * rotationSnap!;
    }

    // Apply rotate
    if (space == 'local' && axis != 'E' && axis != 'XYZE') {
      object.quaternion.setFrom(_quaternionStart);
      object.quaternion
          .multiply(_tempQuaternion.setFromAxisAngle(rotationAxis, rotationAngle))
          .normalize();
    } else {
      rotationAxis.applyQuaternion(_parentQuaternionInv);
      object.quaternion.setFrom(_tempQuaternion.setFromAxisAngle(
          rotationAxis, rotationAngle));
      object.quaternion.multiply(_quaternionStart).normalize();
    }
  }

  dispatchEvent(_changeEvent);
  dispatchEvent(_objectChangeEvent);
}