chore: rearrange library/export structure
This commit is contained in:
15
thermion_dart/lib/src/utils/camera_orientation.dart
Normal file
15
thermion_dart/lib/src/utils/camera_orientation.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:vector_math/vector_math_64.dart' as v;
|
||||
|
||||
class CameraOrientation {
|
||||
v.Vector3 position = v.Vector3(0, 0, 0);
|
||||
|
||||
var rotationX = 0.0;
|
||||
var rotationY = 0.0;
|
||||
var rotationZ = 0.0;
|
||||
|
||||
v.Quaternion compose() {
|
||||
return v.Quaternion.axisAngle(v.Vector3(0, 0, 1), rotationZ) *
|
||||
v.Quaternion.axisAngle(v.Vector3(0, 1, 0), rotationY) *
|
||||
v.Quaternion.axisAngle(v.Vector3(1, 0, 0), rotationX);
|
||||
}
|
||||
}
|
||||
30
thermion_dart/lib/src/utils/dart_resources.dart
Normal file
30
thermion_dart/lib/src/utils/dart_resources.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import '../viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
class DartResourceLoader {
|
||||
static final _assets = <int, Pointer>{};
|
||||
static void loadResource(Pointer<Char> uri, Pointer<ResourceBuffer> out) {
|
||||
try {
|
||||
var data = File(uri.cast<Utf8>().toDartString().replaceAll("file://", ""))
|
||||
.readAsBytesSync();
|
||||
var ptr = calloc<Uint8>(data.lengthInBytes);
|
||||
ptr.asTypedList(data.lengthInBytes).setRange(0, data.lengthInBytes, data);
|
||||
|
||||
out.ref.data = ptr.cast<Void>();
|
||||
out.ref.size = data.lengthInBytes;
|
||||
out.ref.id = _assets.length;
|
||||
_assets[out.ref.id] = ptr;
|
||||
} catch (err) {
|
||||
print(err);
|
||||
out.ref.size = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void freeResource(ResourceBuffer rb) {
|
||||
calloc.free(_assets[rb.id]!);
|
||||
}
|
||||
}
|
||||
334
thermion_dart/lib/src/utils/geometry.dart
Normal file
334
thermion_dart/lib/src/utils/geometry.dart
Normal file
@@ -0,0 +1,334 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../../thermion_dart.dart';
|
||||
|
||||
class GeometryHelper {
|
||||
static Geometry sphere({bool normals = true, bool uvs = true}) {
|
||||
int latitudeBands = 20;
|
||||
int longitudeBands = 20;
|
||||
|
||||
List<double> verticesList = [];
|
||||
List<double> normalsList = [];
|
||||
List<double> uvsList = [];
|
||||
List<int> indices = [];
|
||||
|
||||
for (int latNumber = 0; latNumber <= latitudeBands; latNumber++) {
|
||||
double theta = latNumber * pi / latitudeBands;
|
||||
double sinTheta = sin(theta);
|
||||
double cosTheta = cos(theta);
|
||||
|
||||
for (int longNumber = 0; longNumber <= longitudeBands; longNumber++) {
|
||||
double phi = longNumber * 2 * pi / longitudeBands;
|
||||
double sinPhi = sin(phi);
|
||||
double cosPhi = cos(phi);
|
||||
|
||||
double x = cosPhi * sinTheta;
|
||||
double y = cosTheta;
|
||||
double z = sinPhi * sinTheta;
|
||||
|
||||
verticesList.addAll([x, y, z]);
|
||||
normalsList.addAll([x, y, z]);
|
||||
|
||||
uvsList.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int latNumber = 0; latNumber < latitudeBands; latNumber++) {
|
||||
for (int longNumber = 0; longNumber < longitudeBands; longNumber++) {
|
||||
int first = (latNumber * (longitudeBands + 1)) + longNumber;
|
||||
int second = first + longitudeBands + 1;
|
||||
|
||||
indices.addAll([first, second, first + 1, second, second + 1, first + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
Float32List vertices = Float32List.fromList(verticesList);
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry cube({bool normals = true, bool uvs = true}) {
|
||||
final vertices = Float32List.fromList([
|
||||
// Front face
|
||||
-1, -1, 1,
|
||||
1, -1, 1,
|
||||
1, 1, 1,
|
||||
-1, 1, 1,
|
||||
|
||||
// Back face
|
||||
-1, -1, -1,
|
||||
-1, 1, -1,
|
||||
1, 1, -1,
|
||||
1, -1, -1,
|
||||
|
||||
// Top face
|
||||
-1, 1, -1,
|
||||
-1, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 1, -1,
|
||||
|
||||
// Bottom face
|
||||
-1, -1, -1,
|
||||
1, -1, -1,
|
||||
1, -1, 1,
|
||||
-1, -1, 1,
|
||||
|
||||
// Right face
|
||||
1, -1, -1,
|
||||
1, 1, -1,
|
||||
1, 1, 1,
|
||||
1, -1, 1,
|
||||
|
||||
// Left face
|
||||
-1, -1, -1,
|
||||
-1, -1, 1,
|
||||
-1, 1, 1,
|
||||
-1, 1, -1,
|
||||
]);
|
||||
|
||||
final _normals = normals ? Float32List.fromList([
|
||||
// Front face
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
|
||||
// Back face
|
||||
0, 0, -1,
|
||||
0, 0, -1,
|
||||
0, 0, -1,
|
||||
0, 0, -1,
|
||||
|
||||
// Top face
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
|
||||
// Bottom face
|
||||
0, -1, 0,
|
||||
0, -1, 0,
|
||||
0, -1, 0,
|
||||
0, -1, 0,
|
||||
|
||||
// Right face
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
|
||||
// Left face
|
||||
-1, 0, 0,
|
||||
-1, 0, 0,
|
||||
-1, 0, 0,
|
||||
-1, 0, 0,
|
||||
]) : null;
|
||||
|
||||
final _uvs = uvs ? Float32List.fromList([
|
||||
// Front face
|
||||
1/3, 1/3,
|
||||
2/3, 1/3,
|
||||
2/3, 2/3,
|
||||
1/3, 2/3,
|
||||
|
||||
// Back face
|
||||
2/3, 2/3,
|
||||
2/3, 1,
|
||||
1, 1,
|
||||
1, 2/3,
|
||||
|
||||
// Top face
|
||||
1/3, 0,
|
||||
1/3, 1/3,
|
||||
2/3, 1/3,
|
||||
2/3, 0,
|
||||
|
||||
// Bottom face
|
||||
1/3, 2/3,
|
||||
2/3, 2/3,
|
||||
2/3, 1,
|
||||
1/3, 1,
|
||||
|
||||
// Right face
|
||||
2/3, 1/3,
|
||||
2/3, 2/3,
|
||||
1, 2/3,
|
||||
1, 1/3,
|
||||
|
||||
// Left face
|
||||
0, 1/3,
|
||||
1/3, 1/3,
|
||||
1/3, 2/3,
|
||||
0, 2/3,
|
||||
]) : null;
|
||||
|
||||
final indices = [
|
||||
// Front face
|
||||
0, 1, 2, 0, 2, 3,
|
||||
// Back face
|
||||
4, 5, 6, 4, 6, 7,
|
||||
// Top face
|
||||
8, 9, 10, 8, 10, 11,
|
||||
// Bottom face
|
||||
12, 13, 14, 12, 14, 15,
|
||||
// Right face
|
||||
16, 17, 18, 16, 18, 19,
|
||||
// Left face
|
||||
20, 21, 22, 20, 22, 23
|
||||
];
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry cylinder({double radius = 1.0, double length = 1.0, bool normals = true, bool uvs = true }) {
|
||||
int segments = 32;
|
||||
List<double> verticesList = [];
|
||||
List<double> normalsList = [];
|
||||
List<double> uvsList = [];
|
||||
List<int> indices = [];
|
||||
|
||||
// Create vertices, normals, and UVs
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
double theta = i * 2 * pi / segments;
|
||||
double x = radius * cos(theta);
|
||||
double z = radius * sin(theta);
|
||||
|
||||
// Top circle
|
||||
verticesList.addAll([x, length / 2, z]);
|
||||
normalsList.addAll([x / radius, 0, z / radius]);
|
||||
uvsList.addAll([i / segments, 1]);
|
||||
|
||||
// Bottom circle
|
||||
verticesList.addAll([x, -length / 2, z]);
|
||||
normalsList.addAll([x / radius, 0, z / radius]);
|
||||
uvsList.addAll([i / segments, 0]);
|
||||
}
|
||||
|
||||
// Create indices
|
||||
for (int i = 0; i < segments; i++) {
|
||||
int topFirst = i * 2;
|
||||
int topSecond = (i + 1) * 2;
|
||||
int bottomFirst = topFirst + 1;
|
||||
int bottomSecond = topSecond + 1;
|
||||
|
||||
// Top face (counter-clockwise)
|
||||
indices.addAll([segments * 2, topSecond, topFirst]);
|
||||
// Bottom face (counter-clockwise when viewed from below)
|
||||
indices.addAll([segments * 2 + 1, bottomFirst, bottomSecond]);
|
||||
// Side faces (counter-clockwise)
|
||||
indices.addAll([topFirst, bottomFirst, topSecond]);
|
||||
indices.addAll([bottomFirst, bottomSecond, topSecond]);
|
||||
}
|
||||
|
||||
// Add center vertices, normals, and UVs for top and bottom faces
|
||||
verticesList.addAll([0, length / 2, 0]); // Top center
|
||||
normalsList.addAll([0, 1, 0]);
|
||||
uvsList.addAll([0.5, 0.5]); // Center of top face
|
||||
|
||||
verticesList.addAll([0, -length / 2, 0]); // Bottom center
|
||||
normalsList.addAll([0, -1, 0]);
|
||||
uvsList.addAll([0.5, 0.5]); // Center of bottom face
|
||||
|
||||
// Add top and bottom face normals and UVs
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
normalsList.addAll([0, 1, 0]); // Top face normal
|
||||
normalsList.addAll([0, -1, 0]); // Bottom face normal
|
||||
|
||||
double u = 0.5 + 0.5 * cos(i * 2 * pi / segments);
|
||||
double v = 0.5 + 0.5 * sin(i * 2 * pi / segments);
|
||||
uvsList.addAll([u, v]); // Top face UV
|
||||
uvsList.addAll([u, v]); // Bottom face UV
|
||||
}
|
||||
|
||||
Float32List vertices = Float32List.fromList(verticesList);
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry conic({double radius = 1.0, double length = 1.0, bool normals = true, bool uvs = true}) {
|
||||
int segments = 32;
|
||||
List<double> verticesList = [];
|
||||
List<double> normalsList = [];
|
||||
List<double> uvsList = [];
|
||||
List<int> indices = [];
|
||||
|
||||
// Create vertices, normals, and UVs
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
double theta = i * 2 * pi / segments;
|
||||
double x = radius * cos(theta);
|
||||
double z = radius * sin(theta);
|
||||
|
||||
// Base circle
|
||||
verticesList.addAll([x, 0, z]);
|
||||
|
||||
// Calculate normal for the side
|
||||
double nx = x / sqrt(x * x + length * length);
|
||||
double nz = z / sqrt(z * z + length * length);
|
||||
double ny = radius / sqrt(radius * radius + length * length);
|
||||
normalsList.addAll([nx, ny, nz]);
|
||||
|
||||
// UV coordinates
|
||||
uvsList.addAll([i / segments, 0]);
|
||||
}
|
||||
// Apex
|
||||
verticesList.addAll([0, length, 0]);
|
||||
normalsList.addAll([0, 1, 0]); // Normal at apex points straight up
|
||||
uvsList.addAll([0.5, 1]); // UV for apex
|
||||
|
||||
// Create indices
|
||||
for (int i = 0; i < segments; i++) {
|
||||
// Base face (fixed to counterclockwise)
|
||||
indices.addAll([segments + 1, i + 1, i]);
|
||||
// Side faces (already correct)
|
||||
indices.addAll([i, segments, i + 1]);
|
||||
}
|
||||
|
||||
// Add base face normals and UVs
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
normalsList.addAll([0, -1, 0]); // Base face normal
|
||||
double u = 0.5 + 0.5 * cos(i * 2 * pi / segments);
|
||||
double v = 0.5 + 0.5 * sin(i * 2 * pi / segments);
|
||||
uvsList.addAll([u, v]); // Base face UV
|
||||
}
|
||||
|
||||
Float32List vertices = Float32List.fromList(verticesList);
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry plane({double width = 1.0, double height = 1.0, bool normals = true, bool uvs = true}) {
|
||||
Float32List vertices = Float32List.fromList([
|
||||
-width / 2, 0, -height / 2,
|
||||
width / 2, 0, -height / 2,
|
||||
width / 2, 0, height / 2,
|
||||
-width / 2, 0, height / 2,
|
||||
]);
|
||||
|
||||
Float32List? _normals = normals ? Float32List.fromList([
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
]) : null;
|
||||
|
||||
Float32List? _uvs = uvs ? Float32List.fromList([
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
]) : null;
|
||||
|
||||
List<int> indices = [
|
||||
0, 2, 1,
|
||||
0, 3, 2,
|
||||
];
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
}
|
||||
38
thermion_dart/lib/src/utils/matrix.dart
Normal file
38
thermion_dart/lib/src/utils/matrix.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
// Helper function to convert double4x4 to Matrix4
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:ffi';
|
||||
|
||||
Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
||||
return Matrix4.fromList([
|
||||
mat.col1[0],
|
||||
mat.col1[1],
|
||||
mat.col1[2],
|
||||
mat.col1[3],
|
||||
mat.col2[0],
|
||||
mat.col2[1],
|
||||
mat.col2[2],
|
||||
mat.col2[3],
|
||||
mat.col3[0],
|
||||
mat.col3[1],
|
||||
mat.col3[2],
|
||||
mat.col3[3],
|
||||
mat.col4[0],
|
||||
mat.col4[1],
|
||||
mat.col4[2],
|
||||
mat.col4[3],
|
||||
]);
|
||||
}
|
||||
|
||||
double4x4 matrix4ToDouble4x4(Matrix4 mat) {
|
||||
final out = Struct.create<double4x4>();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
out.col1[i] = mat.storage[i];
|
||||
out.col2[i] = mat.storage[i + 4];
|
||||
out.col3[i] = mat.storage[i + 8];
|
||||
out.col4[i] = mat.storage[i + 12];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user