projectScene method

RenderData projectScene(
  1. Scene scene,
  2. Camera camera,
  3. dynamic sortObjects,
  4. dynamic sortElements,
)

Implementation

RenderData projectScene(Scene scene, Camera camera, sortObjects, sortElements) {
  _faceCount = 0;
  _lineCount = 0;
  _spriteCount = 0;
  _renderData.elements.length = 0;
  if (scene.autoUpdate) scene.updateMatrixWorld();
  if (camera.parent == null) camera.updateMatrixWorld();

  _viewMatrix.copy(camera.matrixWorldInverse);
  _viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix);
  _frustum.setFromProjectionMatrix(_viewProjectionMatrix); //

  _objectCount = 0;
  _renderData.objects.length = 0;
  _renderData.lights.length = 0;
  projectObject(scene);

  if (sortObjects) {
    _renderData.objects.sort(painterSort);
  }

  List<RenderableObject> objects = _renderData.objects;

  for (int o = 0; o < objects.length; o++) {
    Object3D object = objects[o].object!;
    BufferGeometry? geometry = object.geometry;
    setObject(object);
    _modelMatrix = object.matrixWorld;
    _vertexCount = 0;

    if (object is Mesh) {
      Material? material = object.material;
      bool isMultiMaterial = material is List;
      Map<String, dynamic> attributes = geometry!.attributes;
      List<Map<String, dynamic>> groups = geometry.groups;
      if (attributes['position'] == null) continue;
      NativeArray<double> positions = attributes['position'].array;
      for (int i = 0; i < positions.length; i += 3) {
        double x = positions[i];
        double y = positions[i + 1];
        double z = positions[i + 2];
        List<BufferAttribute<NativeArray<num>>>? morphTargets = geometry.morphAttributes['position'];

        if (morphTargets != null) {
          bool morphTargetsRelative = geometry.morphTargetsRelative;
          List<num>? morphInfluences = object.morphTargetInfluences;

          for (int t = 0; t < morphTargets.length; t++) {
            num influence = morphInfluences![t];
            if (influence == 0) continue;
            BufferAttribute<NativeArray<num>>? target = morphTargets[t];
            if (morphTargetsRelative) {
              x += target.getX(i ~/ 3)! * influence;
              y += target.getY(i ~/ 3)! * influence;
              z += target.getZ(i ~/ 3)! * influence;
            } else {
              x += (target.getX(i ~/ 3)! - positions[i]) * influence;
              y += (target.getY(i ~/ 3)! - positions[i + 1]) * influence;
              z += (target.getZ(i ~/ 3)! - positions[i + 2]) * influence;
            }
          }
        }

        pushVertex(x, y, z);
      }

      if (attributes['normal'] != null) {
        NativeArray<double> normals = attributes['normal'].array;
        this.normals += normals.toDartList();
        // for (int i = 0; i < normals.length; i += 3) {
        //   pushNormal(normals[i],normals[i+1], normals[i+2]);
        // }
      }
      if (attributes['color'] != null) {
        NativeArray<double> colors = attributes['color'].array;
        this.colors += colors.toDartList();
        // for(int i = 0; i < colors.length; i += 3 ) {
        //   pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] );
        // }
      }
      if (attributes['uv'] != null) {
        NativeArray<double> uvs = attributes['uv'].array;
        this.uvs += uvs.toDartList();
        // for (int i = 0; i < uvs.length; i += 2 ) {
        //   pushUv( uvs[i], uvs[i + 1]);
        // }
      }
      if (geometry.index != null) {
        NativeArray<num> indices = geometry.index!.array;
        if (groups.isNotEmpty) {
          for (int g = 0; g < groups.length; g++) {
            Map<String, dynamic> group = groups[g];
            material = isMultiMaterial == true ? object.material[group['materialIndex']] : object.material;
            if (material != null) continue;
            for (int i = group['start']; i < group['start'] + group['count']; i += 3) {
              pushTriangle(indices[i], indices[i + 1], indices[i + 2], material!);
            }
          }
        } else {
          for (int i = 0; i < indices.length; i += 3) {
            pushTriangle(indices[i], indices[i + 1], indices[i + 2], material!);
          }
        }
      } else {
        if (groups.isNotEmpty) {
          for (int g = 0; g < groups.length; g++) {
            dynamic group = groups[g];
            material = isMultiMaterial == true ? object.material[group.materialIndex] : object.material;
            if (material == null) continue;
            for (int i = group.start, l = group.start + group.count; i < l; i += 3) {
              pushTriangle(i, i + 1, i + 2, material);
            }
          }
        } else {
          for (int i = 0, l = positions.length ~/ 3; i < l; i += 3) {
            pushTriangle(i, i + 1, i + 2, material!);
          }
        }
      }
    } else if (object is Line) {
      _modelViewProjectionMatrix.multiplyMatrices(_viewProjectionMatrix, _modelMatrix);
      Map<String, dynamic> attributes = geometry!.attributes;

      if (attributes['position'] != null) {
        NativeArray<num> positions = attributes['position'].array;
        for (int i = 0, l = positions.length; i < l; i += 3) {
          pushVertex(positions[i].toDouble(), positions[i + 1].toDouble(), positions[i + 2].toDouble());
        }

        if (attributes['color'] != null) {
          NativeArray<double> colors = attributes['color'].array;
          // for (int i = 0, l = colors.length; i < l; i += 3 ) {
          //   pushColor( colors[ i ].toDouble(), colors[ i + 1 ].toDouble(), colors[ i + 2 ].toDouble());
          // }
          this.colors += colors.toDartList();
        }

        if (geometry.index != null) {
          NativeArray indices = geometry.index!.array;
          for (int i = 0, l = indices.length; i < l; i += 2) {
            pushLine(indices[i], indices[i + 1]);
          }
        } else {
          int step = object is LineSegments ? 2 : 1;
          for (int i = 0, l = positions.length ~/ 3 - 1; i < l; i += step) {
            pushLine(i, i + 1);
          }
        }
      }
    } else if (object is Points) {
      _modelViewProjectionMatrix.multiplyMatrices(_viewProjectionMatrix, _modelMatrix);
      Map<String, dynamic> attributes = geometry!.attributes;
      if (attributes['position'] != null) {
        NativeArray<num> positions = attributes['position'].array;
        for (int i = 0, l = positions.length; i < l; i += 3) {
          _vector4.set(positions[i], positions[i + 1], positions[i + 2], 1);
          _vector4.applyMatrix4(_modelViewProjectionMatrix);
          pushPoint(_vector4, object, camera);
        }
      }
    } else if (object is Sprite) {
      object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld);
      _vector4.set(_modelMatrix.elements[12], _modelMatrix.elements[13], _modelMatrix.elements[14], 1);
      _vector4.applyMatrix4(_viewProjectionMatrix);
      pushPoint(_vector4, object, camera);
    }
  }
  if (sortElements) {
    _renderData.elements.sort(painterSort);
  }

  return _renderData;
}