Skip to content

Commit

Permalink
feat: premature scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
jvenin committed Apr 30, 2024
1 parent c9fea91 commit 4e47c5b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 50 deletions.
19 changes: 8 additions & 11 deletions lib/classes/mesh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class ModelSubMesh {
List<ModelTriangle> triangleToShow,
Float32List normals,
}) getDrawingData(
Rotation rotation,
{
Transformation transformation, {
required ProjectionData projectionData,
Image? overrideTexture,
required int textureWidthOffset,
Expand All @@ -53,7 +52,7 @@ class ModelSubMesh {

final List<ModelTriangle> trianglesToShow = [];
for (final triangle in triangles) {
final shouldShow = triangle.shouldShowTriangle(rotation);
final shouldShow = triangle.shouldShowTriangle(transformation);
if (shouldShow) trianglesToShow.add(triangle.copy(verticesOffset));

for (int j = 0; j < triangle.points.length; j++) {
Expand All @@ -63,24 +62,22 @@ class ModelSubMesh {
if (positions[vertexIndice * 2] != 0) continue;

if (shouldShow) {
if (texture?.imageData != null ||
overrideTexture != null) {
final height = overrideTexture?.height ?? texture!.imageData!.height;
if (texture?.imageData != null || overrideTexture != null) {
final height =
overrideTexture?.height ?? texture!.imageData!.height;
final width = overrideTexture?.width ?? texture!.imageData!.width;
textureCoordinates[vertexIndice * 2] = textureWidthOffset +
(triangle.points[j].textureCoordinates!.x *
width);
(triangle.points[j].textureCoordinates!.x * width);
textureCoordinates[vertexIndice * 2 + 1] =
(1 - triangle.points[j].textureCoordinates!.y) *
height;
(1 - triangle.points[j].textureCoordinates!.y) * height;
}

final projected = triangle.points[j].project(
widthOffset: projectionData.widthOffset,
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
);
normals.addAll([
projected.pointProjection.x,
Expand Down
24 changes: 13 additions & 11 deletions lib/classes/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
Expand Down Expand Up @@ -48,13 +49,6 @@ class Model {
..strokeWidth = 1
..strokeCap = StrokeCap.round;

final textStyle = const TextStyle(
color: Colors.pink,
fontSize: 12,
);
final jointPaint = Paint()
..color = Colors.pink
..strokeWidth = 3;
final skeletonPaint = Paint()
..strokeWidth = 2
..strokeCap = StrokeCap.round;
Expand Down Expand Up @@ -155,7 +149,7 @@ class Model {
}

void draw(
Rotation rotation,
Transformation transformation,
ui.Size size,
ui.Canvas canvas,
Color meshColor,
Expand All @@ -180,7 +174,7 @@ class Model {
// reversing submesh seems to help with rendering order
for (final submesh in mesh.submeshes.reversed) {
final data = submesh.getDrawingData(
rotation,
transformation,
projectionData: projectionData,
overrideTexture: overrideTexture,
textureWidthOffset: overrideTexture == null
Expand All @@ -204,7 +198,7 @@ class Model {
// trying to push deeper triangles to the back
triangles.sort((a, b) {
cmpFnct(double previousValue, ModelVertex element) {
return previousValue + element.transform(rotation).z;
return previousValue + element.transform(transformation).z;
}

final double aWeight = a.points.fold(0.0, cmpFnct);
Expand Down Expand Up @@ -254,6 +248,14 @@ class Model {

if (showSkeleton && skeletons.isNotEmpty) {
skeletonPaint.color = meshColor;
final textStyle = TextStyle(
color: Colors.pink,
fontSize: 12 + transformation.scaleFactor,
fontWeight: FontWeight.bold,
);
final jointPaint = Paint()
..color = Colors.pink
..strokeWidth = 3 + transformation.scaleFactor / 2;
for (final skeleton in skeletons) {
for (final branch in skeleton) {
final List<double> points = [];
Expand All @@ -263,7 +265,7 @@ class Model {
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
);
final idPainter = TextPainter(
text: TextSpan(
Expand Down
18 changes: 13 additions & 5 deletions lib/classes/rotation.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import 'package:vector_math/vector_math.dart';

class Rotation {
Rotation() : quaternion = Quaternion.identity();
class Transformation {
Transformation();

Quaternion quaternion;
Quaternion quaternion = Quaternion.identity();
double scaleFactor = 1;
Matrix4 matrix = Matrix4.identity();

void setQuaternion(
double xRotation,
double yRotation,
double zRotation,
) {
quaternion = Quaternion.euler(zRotation, xRotation, yRotation);
//weird case if we use quaternion.rotate we don't need to invert angles,
//but when using matrix apply it's necessary
quaternion = Quaternion.euler(-zRotation, -xRotation, yRotation);
}

void composeMatrix() {
matrix = Matrix4.compose(Vector3.zero(), quaternion, Vector3.all(scaleFactor));
}

@override
Expand All @@ -20,7 +28,7 @@ class Rotation {

@override
bool operator ==(Object other) =>
other is Rotation && other.quaternion == quaternion;
other is Transformation && other.quaternion == quaternion && other.scaleFactor == scaleFactor;

@override
int get hashCode => quaternion.hashCode;
Expand Down
8 changes: 4 additions & 4 deletions lib/classes/triangle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ class ModelTriangle {
final List<ModelVertex> points;
final List<int> indices;

bool shouldShowTriangle(Rotation rotation) {
final p0 = points[0].transform(rotation);
final p1 = points[1].transform(rotation);
final p2 = points[2].transform(rotation);
bool shouldShowTriangle(Transformation transformation) {
final p0 = points[0].transform(transformation);
final p1 = points[1].transform(transformation);
final p2 = points[2].transform(transformation);
final normal = (p1 - p0).cross(p2 - p0);

// we place our eye at center far from camera, hence -100 in z
Expand Down
21 changes: 13 additions & 8 deletions lib/classes/vertex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ModelVertex {

late Vector3 positions;
late final Vector3 positionOffset;
(Vector3, Quaternion)? lastTransformation;
(Vector3, Quaternion, double)? lastTransformation;
late final BoundingBoxModel box;
Vector2? textureCoordinates;
ModelVertex? normal;
Expand Down Expand Up @@ -66,9 +66,10 @@ class ModelVertex {
((textureSequence >> 8) & 0xFF).toDouble() / 256);
}

Vector3 transform(Rotation rotation) {
Vector3 transform(Transformation transformation) {
if (lastTransformation != null &&
lastTransformation!.$2 == rotation.quaternion) {
lastTransformation!.$2 == transformation.quaternion &&
transformation.scaleFactor == lastTransformation!.$3) {
return lastTransformation!.$1;
}
Vector3 copy = positions.clone();
Expand All @@ -77,7 +78,7 @@ class ModelVertex {
copy.z = -positions.y;
// centering on window
copy -= positionOffset;
rotation.quaternion.rotate(copy);
copy.applyMatrix4(transformation.matrix);
return copy;
}

Expand All @@ -87,10 +88,14 @@ class ModelVertex {
required double heightOffset,
required double maxWidth,
required double maxHeight,
required Rotation rotation,
required Transformation transformation,
}) {
final transformedPoint = transform(rotation);
lastTransformation = (transformedPoint, rotation.quaternion);
final transformedPoint = transform(transformation);
lastTransformation = (
transformedPoint,
transformation.quaternion,
transformation.scaleFactor,
);

double perpectiveFactor = 1.0;

Expand All @@ -105,7 +110,7 @@ class ModelVertex {
heightOffset: heightOffset,
maxWidth: maxWidth,
maxHeight: maxHeight,
rotation: rotation,
transformation: transformation,
)
.pointProjection
);
Expand Down
13 changes: 9 additions & 4 deletions lib/widgets/utils/mouse_movement_notifier.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

Expand All @@ -12,8 +14,7 @@ typedef MouseListener = Widget Function(
ValueNotifier<MousePositionDrag> notifier);

class MouseMovementNotifier extends StatelessWidget {
const MouseMovementNotifier(
{super.key, required this.mouseListener});
const MouseMovementNotifier({super.key, required this.mouseListener});

final MouseListener mouseListener;

Expand Down Expand Up @@ -62,12 +63,16 @@ class MouseMovementNotifier extends StatelessWidget {
},
onPointerSignal: (event) {
if (event is PointerScrollEvent) {
print(event.scrollDelta.dy);
final delta =
event.scrollDelta.dy / MediaQuery.of(context).size.height;
mousePosNotifier.value = (
pos: mousePosNotifier.value.pos,
lastX: mousePosNotifier.value.lastX,
lastY: mousePosNotifier.value.lastY,
zoom:
event.scrollDelta.dy.abs() / MediaQuery.of(context).size.height,
zoom: delta < 0
? max(mousePosNotifier.value.zoom + delta, 1)
: mousePosNotifier.value.zoom + delta,
);
}
},
Expand Down
16 changes: 9 additions & 7 deletions lib/widgets/viewer/model_drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ModelDrawer extends CustomPainter {
final bool showCloth;
final bool showSkeleton;

final Rotation rotation = Rotation();
final Transformation transformation = Transformation();

final Paint _paintHighlight = Paint()
..color = const Color.fromARGB(255, 30, 255, 0)
Expand Down Expand Up @@ -86,7 +86,7 @@ class ModelDrawer extends CustomPainter {
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
)
.pointProjection;

Expand All @@ -96,7 +96,7 @@ class ModelDrawer extends CustomPainter {
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
)
.pointProjection;

Expand All @@ -106,7 +106,7 @@ class ModelDrawer extends CustomPainter {
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
)
.pointProjection;

Expand All @@ -116,7 +116,7 @@ class ModelDrawer extends CustomPainter {
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
transformation: transformation,
)
.pointProjection;

Expand Down Expand Up @@ -167,10 +167,12 @@ class ModelDrawer extends CustomPainter {
2 *
math.pi /
size.height;
rotation.setQuaternion(xRotationAngle, 0, zRotationAngle);
transformation.setQuaternion(xRotationAngle, 0, zRotationAngle);
transformation.scaleFactor = mousePosition.value.zoom;
transformation.composeMatrix();

model.draw(
rotation,
transformation,
size,
canvas,
meshColor,
Expand Down

0 comments on commit 4e47c5b

Please sign in to comment.