projectScene method
RenderData
projectScene(
- Scene scene,
- Camera camera,
- dynamic sortObjects,
- 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;
}