render method

void render(
  1. Scene scene,
  2. Camera camera
)

Implementation

void render(Scene scene, Camera camera) {
  Projector projector = Projector();
  RenderData renderData = RenderData();
  dynamic background = scene.background;

  if (background != null && background.isColor) {
    removeChildNodes();
    svg.style['background-color'] = background.getStyle();
  } else if (autoClear) {
    clear();
  }

  info.vertices = 0;
  info.faces = 0;
  _viewMatrix.copy(camera.matrixWorldInverse);
  _viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix);
  renderData = projector.projectScene(scene, camera, sortObjects, sortElements);
  _elements = renderData.elements;
  lights = renderData.lights;
  _normalViewMatrix.getNormalMatrix(camera.matrixWorldInverse);
  calculateLights(lights!); // reset accumulated path

  _currentPath = '';
  _currentStyle = '';

  for (int e = 0; e < _elements.length; e++) {
    Object3D element = _elements[e];
    Material? material = element.material;
    if (material == null || material.opacity == 0) continue;

    _elemBox.makeEmpty();

    if (element is RenderableSprite) {
      RenderableSprite v1 = element;
      v1.x *= widthHalf;
      v1.y *= -heightHalf;
      renderSprite(v1, element, material);
    } else if (element is RenderableLine) {
      RenderableVertex v1 = element.v1;
      RenderableVertex v2 = element.v2;

      v1.positionScreen.x *= widthHalf;
      v1.positionScreen.y *= -heightHalf;
      v2.positionScreen.x *= widthHalf;
      v2.positionScreen.y *= -heightHalf;

      _elemBox.setFromPoints([v1.positionScreen.toVector2(), v2.positionScreen.toVector2()]);

      if (_clipBox.intersectsBox(_elemBox)) {
        renderLine(v1, v2, material);
      }
    } else if (element is RenderableFace) {
      RenderableVertex v1 = element.v1;
      RenderableVertex v2 = element.v2;
      RenderableVertex v3 = element.v3;
      if (v1.positionScreen.z < -1 || v1.positionScreen.z > 1) continue;
      if (v2.positionScreen.z < -1 || v2.positionScreen.z > 1) continue;
      if (v3.positionScreen.z < -1 || v3.positionScreen.z > 1) continue;
      v1.positionScreen.x *= widthHalf;
      v1.positionScreen.y *= -heightHalf;
      v2.positionScreen.x *= widthHalf;
      v2.positionScreen.y *= -heightHalf;
      v3.positionScreen.x *= widthHalf;
      v3.positionScreen.y *= -heightHalf;

      if (overdraw > 0) {
        expand(v1.positionScreen, v2.positionScreen, overdraw);
        expand(v2.positionScreen, v3.positionScreen, overdraw);
        expand(v3.positionScreen, v1.positionScreen, overdraw);
      }

      _elemBox.setFromPoints(
          [v1.positionScreen.toVector2(), v2.positionScreen.toVector2(), v3.positionScreen.toVector2()]);

      if (_clipBox.intersectsBox(_elemBox)) {
        renderFace3(v1, v2, v3, element, material);
      }
    }
  }

  flushPath(); // just to flush last svg:path

  scene.traverseVisible((object) {
    if (object is SVGObject) {
      _vector3.setFromMatrixPosition(object.matrixWorld);
      _vector3.applyMatrix4(_viewProjectionMatrix);

      if (_vector3.z < -1 || _vector3.z > 1) return;
      double x = _vector3.x * widthHalf;
      double y = -_vector3.y * heightHalf;
      SVGDocument node = object.node;
      node.setAttribute('transform', 'translate($x,$y)');
      svg.appendChild(node);
    }
  });
}