Skip to content

Commit

Permalink
feat: obj converter updated
Browse files Browse the repository at this point in the history
  • Loading branch information
jvenin committed Apr 1, 2024
1 parent 2961e33 commit 83fff66
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 75 deletions.
18 changes: 8 additions & 10 deletions lib/classes/gsf/header2/chunks/mesh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import 'package:paraworld_gsf_viewer/classes/gsf/header2/chunks/chunk.dart';
import 'package:paraworld_gsf_viewer/classes/gsf/header2/chunks/submesh.dart';
import 'package:paraworld_gsf_viewer/classes/gsf_data.dart';
import 'package:paraworld_gsf_viewer/classes/model.dart';
import 'package:paraworld_gsf_viewer/classes/triangle.dart';
import 'package:paraworld_gsf_viewer/classes/vertex.dart';
import 'package:vector_math/vector_math.dart';

mixin MeshToModelInterface on Chunk {
Expand All @@ -16,17 +14,17 @@ mixin MeshToModelInterface on Chunk {
Matrix4 get matrix;
Model toModel() {
final globalBB = boundingBox.toModelBox();
final List<ModelVertex> vertices = [];
final List<ModelTriangle> triangles = [];
final List<ModelMesh> meshes = [];
for (var submesh in submeshes) {
final data = submesh.getMeshModelData(vertices.length, globalBB, matrix);
vertices.addAll(data.vertices);
triangles.addAll(data.triangles);
final data = submesh.getMeshModelData(
0,
globalBB,
matrix,
);
meshes.add((vertices: data.vertices, triangles: data.triangles));
}
return Model(

vertices: vertices,
triangles: triangles,
meshes: meshes,
boundingBox: globalBB,
);
}
Expand Down
88 changes: 48 additions & 40 deletions lib/classes/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ import 'package:paraworld_gsf_viewer/classes/triangle.dart';
import 'package:paraworld_gsf_viewer/classes/vertex.dart';
import 'dart:math' as math;

typedef ModelMesh = ({
List<ModelVertex> vertices,
List<ModelTriangle> triangles
});

class Model {
Model({
required this.vertices,
required this.triangles,
required this.meshes,
required this.boundingBox,
});

final List<ModelVertex> vertices;
final List<ModelTriangle> triangles;
final List<ModelMesh> meshes;
final BoundingBoxModel boundingBox;
//final Vector3 scale;

Expand Down Expand Up @@ -49,54 +52,59 @@ class Model {
bool showNormals = false,
}) {
final projectionData = getProjectionData(size);
final verticesLength = meshes.fold<int>(
0, (previousValue, element) => previousValue + element.vertices.length);

final Float32List positions =
Float32List.fromList(List<double>.filled(vertices.length * 2, 0));
Float32List.fromList(List<double>.filled(verticesLength * 2, 0));
final Float32List textureCoordinates =
Float32List.fromList(List<double>.filled(vertices.length * 2, 0));
Float32List.fromList(List<double>.filled(verticesLength * 2, 0));
final List<double> normals = [];
final List<int> indices = [];
for (final triangle in triangles) {
final shouldShow = triangle.shouldShowTriangle(rotation);
int indicesOffset = 0;
for (final mesh in meshes) {
for (final triangle in mesh.triangles) {
final shouldShow = triangle.shouldShowTriangle(rotation);

for (int j = 0; j < triangle.points.length; j++) {
final vertexIndice = triangle.indices[j];
if (shouldShow) indices.add(vertexIndice);
for (int j = 0; j < triangle.points.length; j++) {
final vertexIndice = indicesOffset + triangle.indices[j];
if (shouldShow) indices.add(vertexIndice);

if (positions[vertexIndice * 2] != 0) continue;
if (positions[vertexIndice * 2] != 0) continue;

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

final projected = triangle.points[j].project(
widthOffset: projectionData.widthOffset,
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
);
normals.addAll([
projected.pointProjection.x,
projected.pointProjection.y,
projected.normalProjection!.x,
projected.normalProjection!.y,
]);
final projected = triangle.points[j].project(
widthOffset: projectionData.widthOffset,
heightOffset: projectionData.heightOffset,
maxWidth: projectionData.maxFactor,
maxHeight: projectionData.maxFactor,
rotation: rotation,
);
normals.addAll([
projected.pointProjection.x,
projected.pointProjection.y,
projected.normalProjection!.x,
projected.normalProjection!.y,
]);

positions[vertexIndice * 2] = projected.pointProjection.x;
positions[vertexIndice * 2 + 1] = projected.pointProjection.y;
} else {
positions[vertexIndice * 2] = 0;
positions[vertexIndice * 2 + 1] = 0;
positions[vertexIndice * 2] = projected.pointProjection.x;
positions[vertexIndice * 2 + 1] = projected.pointProjection.y;
} else {
positions[vertexIndice * 2] = 0;
positions[vertexIndice * 2 + 1] = 0;
}
}
}

indicesOffset += mesh.vertices.length;
//canvas.drawRawPoints(PointMode.points, positions.lenght, _paint);
}
return (
Expand Down
4 changes: 2 additions & 2 deletions lib/classes/triangle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class ModelTriangle {
return normal.dot(p0 - Vector3(0, 0, -100)) <= 0;
}

String toObj() {
return "f ${indices[0] + 1}/${indices[0] + 1}/${indices[0] + 1} ${indices[1] + 1}/${indices[1] + 1}/${indices[1] + 1} ${indices[2] + 1}/${indices[2] + 1}/${indices[2] + 1}\n";
String toObj(int offset) {
return "f ${indices[0] + 1 + offset}/${indices[0] + 1 + offset}/${indices[0] + 1 + offset} ${indices[1] + 1 + offset}/${indices[1] + 1 + offset}/${indices[1] + 1 + offset} ${indices[2] + 1 + offset}/${indices[2] + 1 + offset}/${indices[2] + 1 + offset}\n";
}

@override
Expand Down
7 changes: 5 additions & 2 deletions lib/classes/vertex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,12 @@ class ModelVertex {
}

(String, String, String) toObj() {
// converting to paraworld coordinate system
//copy.y = copy.z;
//copy.z = -positions.y;
return (
"v ${-positions.x} ${positions.y} ${-positions.z} 1.0",
"vn ${(-(normal?.positions.x ?? 0)).toStringAsFixed(3)} ${(normal?.positions.y ?? 0).toStringAsFixed(3)} ${(-(normal?.positions.z ?? 0)).toStringAsFixed(3)}",
"v ${-positions.x} ${positions.z} ${positions.y} 1.0",
"vn ${(-(normal?.positions.x ?? 0)).toStringAsFixed(3)} ${(normal?.positions.z ?? 0).toStringAsFixed(3)} ${((normal?.positions.y ?? 0)).toStringAsFixed(3)}",
"vt ${textureCoordinates?.x ?? 0} ${(textureCoordinates?.y ?? 0)}"
);
}
Expand Down
38 changes: 21 additions & 17 deletions lib/widgets/convert_to_obj_cta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:paraworld_gsf_viewer/classes/triangle.dart';
import 'package:paraworld_gsf_viewer/classes/vertex.dart';
import 'package:paraworld_gsf_viewer/classes/model.dart';
import 'package:paraworld_gsf_viewer/widgets/utils/buttons.dart';
import 'package:paraworld_gsf_viewer/widgets/utils/label.dart';

class ConvertToObjCta extends StatelessWidget {
const ConvertToObjCta({
super.key,
required this.vertices,
required this.triangles,
required this.model,
});

final List<ModelVertex> vertices;
final List<ModelTriangle> triangles;
final Model model;

Future<String?> writeAsObj() async {
String? outputFile = await FilePicker.platform.saveFile(
Expand All @@ -29,19 +26,26 @@ class ConvertToObjCta extends StatelessWidget {
// User canceled the picker
}
final objFile = File(outputFile);
String vertexPart = "", normalPart = "", texturePart = "";
for (final vertex in vertices) {
final newContent = vertex.toObj();
vertexPart += "${newContent.$1}\n";
normalPart += "${newContent.$2}\n";
texturePart += "${newContent.$3}\n";
}
String fileContent = "$vertexPart\n$normalPart\n$texturePart\n";
String fileContent = "";
int offset = 0;
for (final mesh in model.meshes) {
fileContent += "\n\no ${mesh.hashCode}\n\n";
fileContent += "# offset of group for triangles indices $offset\n\n";
String vertexPart = "", normalPart = "", texturePart = "";
for (final vertex in mesh.vertices) {
final newContent = vertex.toObj();
vertexPart += "${newContent.$1}\n";
normalPart += "${newContent.$2}\n";
texturePart += "${newContent.$3}\n";
}
fileContent += "$vertexPart\n$normalPart\n$texturePart\n";

for (final triangle in triangles) {
fileContent += triangle.toObj();
for (final triangle in mesh.triangles) {
fileContent += triangle.toObj(offset);
}
offset += mesh.vertices.length;
}
objFile.writeAsString(fileContent);
await objFile.writeAsString(fileContent);
return objFile.path;
}

Expand Down
8 changes: 6 additions & 2 deletions lib/widgets/header2/widgets/chunks/submesh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ class SubmeshDisplay extends StatelessWidget {
null,
);
final Model model = Model(
vertices: modelData.vertices,
triangles: modelData.triangles,
meshes: [
(
vertices: modelData.vertices,
triangles: modelData.triangles,
)
],
boundingBox: modelData.box,
);
return Flexible(
Expand Down
3 changes: 1 addition & 2 deletions lib/widgets/viewer/viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ class Viewer extends StatelessWidget {
),
),
ConvertToObjCta(
vertices: model!.vertices,
triangles: model!.triangles,
model: model!,
),
],
);
Expand Down

0 comments on commit 83fff66

Please sign in to comment.