more refactoring
This commit is contained in:
@@ -32,7 +32,8 @@ class GeometryHelper {
|
|||||||
verticesList.addAll([x, y, z]);
|
verticesList.addAll([x, y, z]);
|
||||||
normalsList.addAll([x, y, z]);
|
normalsList.addAll([x, y, z]);
|
||||||
|
|
||||||
uvsList.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
uvsList
|
||||||
|
.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +42,8 @@ class GeometryHelper {
|
|||||||
int first = (latNumber * (longitudeBands + 1)) + longNumber;
|
int first = (latNumber * (longitudeBands + 1)) + longNumber;
|
||||||
int second = first + longitudeBands + 1;
|
int second = first + longitudeBands + 1;
|
||||||
|
|
||||||
indices.addAll([first, second, first + 1, second, second + 1, first + 1]);
|
indices
|
||||||
|
.addAll([first, second, first + 1, second, second + 1, first + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,139 +54,184 @@ class GeometryHelper {
|
|||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Geometry cube({bool normals = true, bool uvs = true}) {
|
static Geometry cube({bool normals = true, bool uvs = true}) {
|
||||||
final vertices = Float32List.fromList([
|
final vertices = Float32List.fromList([
|
||||||
// Front face
|
// Front face
|
||||||
-1, -1, 1,
|
-1, -1, 1, // 0
|
||||||
1, -1, 1,
|
1, -1, 1, // 1
|
||||||
1, 1, 1,
|
1, 1, 1, // 2
|
||||||
-1, 1, 1,
|
-1, 1, 1, // 3
|
||||||
|
|
||||||
// Back face
|
// Back face
|
||||||
-1, -1, -1,
|
-1, -1, -1, // 4
|
||||||
-1, 1, -1,
|
1, -1, -1, // 5
|
||||||
1, 1, -1,
|
1, 1, -1, // 6
|
||||||
1, -1, -1,
|
-1, 1, -1, // 7
|
||||||
|
|
||||||
// Top face
|
// Top face
|
||||||
-1, 1, -1,
|
-1, 1, 1, // 3 (8)
|
||||||
-1, 1, 1,
|
1, 1, 1, //2 (9)
|
||||||
1, 1, 1,
|
1, 1, -1, //6 (10)
|
||||||
1, 1, -1,
|
-1, 1, -1, // 7 (11)
|
||||||
|
|
||||||
// Bottom face
|
// Bottom
|
||||||
-1, -1, -1,
|
-1, -1, -1, // 4 (12)
|
||||||
1, -1, -1,
|
1, -1, -1, // 5 (13)
|
||||||
1, -1, 1,
|
1, -1, 1, // 1 (14)
|
||||||
-1, -1, 1,
|
-1, -1, 1, // 0 (15)
|
||||||
|
|
||||||
// Right face
|
// Right
|
||||||
1, -1, -1,
|
1, -1, 1, // 1 (16)
|
||||||
1, 1, -1,
|
1, -1, -1, // 5 (17)
|
||||||
1, 1, 1,
|
1, 1, -1, // 6 (18)
|
||||||
1, -1, 1,
|
1, 1, 1, // 2 (19)
|
||||||
|
|
||||||
// Left face
|
// Left
|
||||||
-1, -1, -1,
|
-1, -1, -1, // 4 (20)
|
||||||
-1, -1, 1,
|
-1, -1, 1, // 0 (21)
|
||||||
-1, 1, 1,
|
-1, 1, 1, // 3 (22)
|
||||||
-1, 1, -1,
|
-1, 1, -1 // 7 (23)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
final _normals = normals ? Float32List.fromList([
|
final _normals = normals
|
||||||
// Front face
|
? Float32List.fromList([
|
||||||
0, 0, 1,
|
0,
|
||||||
0, 0, 1,
|
0,
|
||||||
0, 0, 1,
|
1,
|
||||||
0, 0, 1,
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
// Back face
|
final _uvs = uvs
|
||||||
0, 0, -1,
|
? Float32List.fromList([
|
||||||
0, 0, -1,
|
// front
|
||||||
0, 0, -1,
|
1 / 3, 3 / 4, // 0
|
||||||
0, 0, -1,
|
2 / 3, 3 / 4, // 1
|
||||||
|
2 / 3, 1, // 2
|
||||||
|
1 / 3, 1, // 3
|
||||||
|
|
||||||
// Top face
|
// back
|
||||||
0, 1, 0,
|
1 / 3, 1 / 4, // 4
|
||||||
0, 1, 0,
|
2 / 3, 1 / 4, // 5
|
||||||
0, 1, 0,
|
2 / 3, 1 / 2, // 6
|
||||||
0, 1, 0,
|
1 / 3, 1 / 2, // 7
|
||||||
|
|
||||||
// Bottom face
|
// top
|
||||||
0, -1, 0,
|
2 / 3, 1 / 2, // 8
|
||||||
0, -1, 0,
|
1, 1 / 2, // 9
|
||||||
0, -1, 0,
|
1, 3 / 4, // 10
|
||||||
0, -1, 0,
|
2 / 3, 3 / 4, // 11
|
||||||
|
|
||||||
// Right face
|
// bottom
|
||||||
1, 0, 0,
|
0, 1 / 2, // 12
|
||||||
1, 0, 0,
|
1 / 3, 1 / 2, // 13
|
||||||
1, 0, 0,
|
1 / 3, 3 / 4, // 14
|
||||||
1, 0, 0,
|
0, 3 / 4, // 15
|
||||||
|
|
||||||
// Left face
|
// right
|
||||||
-1, 0, 0,
|
1 / 3, 1 / 2, // 16
|
||||||
-1, 0, 0,
|
2 / 3, 1 / 2, // 17
|
||||||
-1, 0, 0,
|
2 / 3, 3 / 4, // 18
|
||||||
-1, 0, 0,
|
1 / 3, 3 / 4, // 19
|
||||||
]) : null;
|
|
||||||
|
|
||||||
final _uvs = uvs ? Float32List.fromList([
|
// left
|
||||||
// Front face
|
1 / 3, 0, // 20
|
||||||
1/3, 1/3,
|
2 / 3, 0, // 21
|
||||||
2/3, 1/3,
|
2 / 3, 1 / 4, // 22
|
||||||
2/3, 2/3,
|
1 / 3, 1 / 4 // 23
|
||||||
1/3, 2/3,
|
])
|
||||||
|
: null;
|
||||||
// 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 = [
|
final indices = [
|
||||||
// Front face
|
// Front face
|
||||||
0, 1, 2, 0, 2, 3,
|
0, 1, 2, 0, 2, 3,
|
||||||
// Back face
|
// Back face
|
||||||
4, 5, 6, 4, 6, 7,
|
5, 4, 7, 5, 7, 6,
|
||||||
// Top face
|
// Top face
|
||||||
8, 9, 10, 8, 10, 11,
|
8, 9, 10, 8, 10, 11, // 3,2,6,3,6,7, //
|
||||||
// Bottom face
|
// Bottom face
|
||||||
12, 13, 14, 12, 14, 15,
|
12, 13, 14, 12, 14, 15, // 4,5,1,4,1,0,
|
||||||
// Right face
|
// Right face
|
||||||
16, 17, 18, 16, 18, 19,
|
16, 17, 18, 16, 18, 19, //1,5,6,1,6,2,
|
||||||
// Left face
|
// Left face
|
||||||
20, 21, 22, 20, 22, 23
|
20, 21, 22, 20, 22, 23 // 4,0,3,4,3,7
|
||||||
];
|
];
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
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 }) {
|
static Geometry cylinder(
|
||||||
|
{double radius = 1.0,
|
||||||
|
double length = 1.0,
|
||||||
|
bool normals = true,
|
||||||
|
bool uvs = true}) {
|
||||||
int segments = 32;
|
int segments = 32;
|
||||||
List<double> verticesList = [];
|
List<double> verticesList = [];
|
||||||
List<double> normalsList = [];
|
List<double> normalsList = [];
|
||||||
@@ -251,7 +298,11 @@ static Geometry cube({bool normals = true, bool uvs = true}) {
|
|||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
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}) {
|
static Geometry conic(
|
||||||
|
{double radius = 1.0,
|
||||||
|
double length = 1.0,
|
||||||
|
bool normals = true,
|
||||||
|
bool uvs = true}) {
|
||||||
int segments = 32;
|
int segments = 32;
|
||||||
List<double> verticesList = [];
|
List<double> verticesList = [];
|
||||||
List<double> normalsList = [];
|
List<double> normalsList = [];
|
||||||
@@ -369,24 +420,47 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
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}) {
|
static Geometry plane(
|
||||||
|
{double width = 1.0,
|
||||||
|
double height = 1.0,
|
||||||
|
bool normals = true,
|
||||||
|
bool uvs = true}) {
|
||||||
Float32List vertices = Float32List.fromList([
|
Float32List vertices = Float32List.fromList([
|
||||||
-width / 2, 0, -height / 2,
|
-width / 2,
|
||||||
width / 2, 0, -height / 2,
|
0,
|
||||||
width / 2, 0, height / 2,
|
-height / 2,
|
||||||
-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([
|
Float32List? _normals = normals
|
||||||
0, 1, 0,
|
? Float32List.fromList([
|
||||||
0, 1, 0,
|
0,
|
||||||
0, 1, 0,
|
1,
|
||||||
0, 1, 0,
|
0,
|
||||||
]) : null;
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList([
|
Float32List? _uvs =
|
||||||
|
uvs ? Float32List.fromList([
|
||||||
0, 0,
|
0, 0,
|
||||||
1, 0,
|
1, 0,
|
||||||
1, 1,
|
1, 1,
|
||||||
@@ -394,8 +468,12 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
]) : null;
|
]) : null;
|
||||||
|
|
||||||
List<int> indices = [
|
List<int> indices = [
|
||||||
0, 2, 1,
|
0,
|
||||||
0, 3, 2,
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
];
|
];
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
@@ -409,7 +487,7 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
double fov = pi / 3,
|
double fov = pi / 3,
|
||||||
bool normals = true,
|
bool normals = true,
|
||||||
bool uvs = true,
|
bool uvs = true,
|
||||||
}) {
|
}) {
|
||||||
List<double> verticesList = [];
|
List<double> verticesList = [];
|
||||||
List<double> normalsList = [];
|
List<double> normalsList = [];
|
||||||
List<double> uvsList = [];
|
List<double> uvsList = [];
|
||||||
@@ -435,8 +513,10 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
double z = sphereRadius * sinPhi * sinTheta;
|
double z = sphereRadius * sinPhi * sinTheta;
|
||||||
|
|
||||||
verticesList.addAll([x, y, z]);
|
verticesList.addAll([x, y, z]);
|
||||||
normalsList.addAll([x / sphereRadius, y / sphereRadius, z / sphereRadius]);
|
normalsList
|
||||||
uvsList.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
.addAll([x / sphereRadius, y / sphereRadius, z / sphereRadius]);
|
||||||
|
uvsList
|
||||||
|
.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,19 +557,19 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
|
|
||||||
// Add near rectangle vertices (negative z)
|
// Add near rectangle vertices (negative z)
|
||||||
verticesList.addAll([
|
verticesList.addAll([
|
||||||
-nearWidth/2, -nearHeight/2, -frustumNear, // Bottom-left
|
-nearWidth / 2, -nearHeight / 2, -frustumNear, // Bottom-left
|
||||||
nearWidth/2, -nearHeight/2, -frustumNear, // Bottom-right
|
nearWidth / 2, -nearHeight / 2, -frustumNear, // Bottom-right
|
||||||
nearWidth/2, nearHeight/2, -frustumNear, // Top-right
|
nearWidth / 2, nearHeight / 2, -frustumNear, // Top-right
|
||||||
-nearWidth/2, nearHeight/2, -frustumNear, // Top-left
|
-nearWidth / 2, nearHeight / 2, -frustumNear, // Top-left
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Add far rectangle vertices (negative z)
|
// Add far rectangle vertices (negative z)
|
||||||
int farBaseIndex = verticesList.length ~/ 3;
|
int farBaseIndex = verticesList.length ~/ 3;
|
||||||
verticesList.addAll([
|
verticesList.addAll([
|
||||||
-farWidth/2, -farHeight/2, -frustumFar, // Bottom-left
|
-farWidth / 2, -farHeight / 2, -frustumFar, // Bottom-left
|
||||||
farWidth/2, -farHeight/2, -frustumFar, // Bottom-right
|
farWidth / 2, -farHeight / 2, -frustumFar, // Bottom-right
|
||||||
farWidth/2, farHeight/2, -frustumFar, // Top-right
|
farWidth / 2, farHeight / 2, -frustumFar, // Top-right
|
||||||
-farWidth/2, farHeight/2, -frustumFar, // Top-left
|
-farWidth / 2, farHeight / 2, -frustumFar, // Top-left
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Add normals and UVs for frustum vertices
|
// Add normals and UVs for frustum vertices
|
||||||
@@ -534,16 +614,12 @@ static Geometry conic({double radius = 1.0, double length = 1.0, bool normals =
|
|||||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||||
|
|
||||||
return Geometry(
|
return Geometry(vertices, indices,
|
||||||
vertices,
|
normals: _normals, uvs: _uvs, primitiveType: PrimitiveType.LINES);
|
||||||
indices,
|
}
|
||||||
normals: _normals,
|
|
||||||
uvs: _uvs,
|
|
||||||
primitiveType: PrimitiveType.LINES
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
static Geometry fromAabb3(Aabb3 aabb,
|
||||||
|
{bool normals = true, bool uvs = true}) {
|
||||||
// Get the center and half extents from the AABB
|
// Get the center and half extents from the AABB
|
||||||
final center = aabb.center;
|
final center = aabb.center;
|
||||||
final halfExtents = Vector3.zero();
|
final halfExtents = Vector3.zero();
|
||||||
@@ -552,43 +628,68 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
// Create vertices list with transformed coordinates
|
// Create vertices list with transformed coordinates
|
||||||
final vertices = Float32List.fromList([
|
final vertices = Float32List.fromList([
|
||||||
// Front face
|
// Front face
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.z + halfExtents.z,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.z + halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
|
||||||
// Back face
|
// Back face
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z - halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
|
center.z - halfExtents.z,
|
||||||
|
|
||||||
// Top face
|
// Top face
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.z + halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z - halfExtents.z,
|
||||||
|
|
||||||
// Bottom face
|
// Bottom face
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
|
||||||
// Right face
|
// Right face
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
center.x + halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
center.x + halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
center.x + halfExtents.x, center.y - halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
|
||||||
// Left face
|
// Left face
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z - halfExtents.z,
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y - halfExtents.y, center.z + halfExtents.z,
|
center.z - halfExtents.z,
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z + halfExtents.z,
|
center.x - halfExtents.x, center.y - halfExtents.y,
|
||||||
center.x - halfExtents.x, center.y + halfExtents.y, center.z - halfExtents.z,
|
center.z + halfExtents.z,
|
||||||
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z + halfExtents.z,
|
||||||
|
center.x - halfExtents.x, center.y + halfExtents.y,
|
||||||
|
center.z - halfExtents.z,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
final _normals = normals ? Float32List.fromList([
|
final _normals = normals
|
||||||
|
? Float32List.fromList([
|
||||||
// Front face
|
// Front face
|
||||||
0, 0, 1,
|
0, 0, 1,
|
||||||
0, 0, 1,
|
0, 0, 1,
|
||||||
@@ -624,45 +725,48 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
-1, 0, 0,
|
-1, 0, 0,
|
||||||
-1, 0, 0,
|
-1, 0, 0,
|
||||||
-1, 0, 0,
|
-1, 0, 0,
|
||||||
]) : null;
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
final _uvs = uvs ? Float32List.fromList([
|
final _uvs = uvs
|
||||||
|
? Float32List.fromList([
|
||||||
// Front face
|
// Front face
|
||||||
1/3, 1/3,
|
1 / 3, 1 / 3,
|
||||||
2/3, 1/3,
|
2 / 3, 1 / 3,
|
||||||
2/3, 2/3,
|
2 / 3, 2 / 3,
|
||||||
1/3, 2/3,
|
1 / 3, 2 / 3,
|
||||||
|
|
||||||
// Back face
|
// Back face
|
||||||
2/3, 2/3,
|
2 / 3, 2 / 3,
|
||||||
2/3, 1,
|
2 / 3, 1,
|
||||||
1, 1,
|
1, 1,
|
||||||
1, 2/3,
|
1, 2 / 3,
|
||||||
|
|
||||||
// Top face
|
// Top face
|
||||||
1/3, 0,
|
1 / 3, 0,
|
||||||
1/3, 1/3,
|
1 / 3, 1 / 3,
|
||||||
2/3, 1/3,
|
2 / 3, 1 / 3,
|
||||||
2/3, 0,
|
2 / 3, 0,
|
||||||
|
|
||||||
// Bottom face
|
// Bottom face
|
||||||
1/3, 2/3,
|
1 / 3, 2 / 3,
|
||||||
2/3, 2/3,
|
2 / 3, 2 / 3,
|
||||||
2/3, 1,
|
2 / 3, 1,
|
||||||
1/3, 1,
|
1 / 3, 1,
|
||||||
|
|
||||||
// Right face
|
// Right face
|
||||||
2/3, 1/3,
|
2 / 3, 1 / 3,
|
||||||
2/3, 2/3,
|
2 / 3, 2 / 3,
|
||||||
1, 2/3,
|
1, 2 / 3,
|
||||||
1, 1/3,
|
1, 1 / 3,
|
||||||
|
|
||||||
// Left face
|
// Left face
|
||||||
0, 1/3,
|
0, 1 / 3,
|
||||||
1/3, 1/3,
|
1 / 3, 1 / 3,
|
||||||
1/3, 2/3,
|
1 / 3, 2 / 3,
|
||||||
0, 2/3,
|
0, 2 / 3,
|
||||||
]) : null;
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
final indices = [
|
final indices = [
|
||||||
// Front face
|
// Front face
|
||||||
@@ -682,15 +786,14 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Geometry halfPyramid({
|
static Geometry halfPyramid(
|
||||||
double startX = 0.25,
|
{double startX = 0.25,
|
||||||
double startY = 0.25,
|
double startY = 0.25,
|
||||||
double width = 1.0,
|
double width = 1.0,
|
||||||
double height = 1.0,
|
double height = 1.0,
|
||||||
double depth = 1.0,
|
double depth = 1.0,
|
||||||
bool normals = true,
|
bool normals = true,
|
||||||
bool uvs = true
|
bool uvs = true}) {
|
||||||
}) {
|
|
||||||
// Define vertices for a half pyramid (triangular prism)
|
// Define vertices for a half pyramid (triangular prism)
|
||||||
// Starting at (startX, startY, 0)
|
// Starting at (startX, startY, 0)
|
||||||
Float32List vertices = Float32List.fromList([
|
Float32List vertices = Float32List.fromList([
|
||||||
@@ -706,7 +809,8 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Define normals if needed
|
// Define normals if needed
|
||||||
Float32List? _normals = normals ? Float32List.fromList([
|
Float32List? _normals = normals
|
||||||
|
? Float32List.fromList([
|
||||||
// Base rectangle
|
// Base rectangle
|
||||||
0, 0, -1, // Bottom face
|
0, 0, -1, // Bottom face
|
||||||
0, 0, -1,
|
0, 0, -1,
|
||||||
@@ -716,10 +820,12 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
// Ridge normals (approximate)
|
// Ridge normals (approximate)
|
||||||
0, 0.7071, 0.7071, // Angled toward ridge
|
0, 0.7071, 0.7071, // Angled toward ridge
|
||||||
0, 0.7071, 0.7071,
|
0, 0.7071, 0.7071,
|
||||||
]) : null;
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
// Define UVs if needed
|
// Define UVs if needed
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList([
|
Float32List? _uvs = uvs
|
||||||
|
? Float32List.fromList([
|
||||||
// Base rectangle UVs
|
// Base rectangle UVs
|
||||||
0, 0, // Bottom-left
|
0, 0, // Bottom-left
|
||||||
1, 0, // Bottom-right
|
1, 0, // Bottom-right
|
||||||
@@ -729,7 +835,8 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
// Ridge UVs
|
// Ridge UVs
|
||||||
0, 0.5,
|
0, 0.5,
|
||||||
1, 0.5,
|
1, 0.5,
|
||||||
]) : null;
|
])
|
||||||
|
: null;
|
||||||
|
|
||||||
// Define indices for triangular faces
|
// Define indices for triangular faces
|
||||||
List<int> indices = [
|
List<int> indices = [
|
||||||
@@ -753,6 +860,5 @@ static Geometry fromAabb3(Aabb3 aabb, {bool normals = true, bool uvs = true}) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
@@ -10,34 +11,18 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
final Pointer<TSceneAsset> pointer;
|
final Pointer<TSceneAsset> asset;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
final Pointer<TSceneManager> sceneManager;
|
final FFIFilamentApp app;
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
Pointer<TRenderableManager> get renderableManager =>
|
|
||||||
Engine_getRenderableManager(engine);
|
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
final Pointer<TEngine> engine;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
FFIAsset? _highlight;
|
FFIAsset? _highlight;
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
final Pointer<TMaterialProvider> _unlitMaterialProvider;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -48,22 +33,15 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
late final ThermionEntity entity;
|
late final ThermionEntity entity;
|
||||||
|
|
||||||
///
|
FFIAsset(this.asset, this.app, {this.isInstance = false}) {
|
||||||
///
|
entity = SceneAsset_getEntity(asset);
|
||||||
///
|
|
||||||
final ThermionViewer viewer;
|
|
||||||
|
|
||||||
FFIAsset(this.pointer, this.sceneManager, this.engine,
|
|
||||||
this._unlitMaterialProvider, this.viewer,
|
|
||||||
{this.isInstance = false}) {
|
|
||||||
entity = SceneAsset_getEntity(pointer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<ThermionEntity>> getChildEntities() async {
|
Future<List<ThermionEntity>> getChildEntities() async {
|
||||||
var count = SceneAsset_getChildEntityCount(pointer);
|
var count = SceneAsset_getChildEntityCount(asset);
|
||||||
var children = Int32List(count);
|
var children = Int32List(count);
|
||||||
SceneAsset_getChildEntities(pointer, children.address);
|
SceneAsset_getChildEntities(asset, children.address);
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +51,11 @@ class FFIAsset extends ThermionAsset {
|
|||||||
throw Exception(
|
throw Exception(
|
||||||
"This is itself an instance. Call getInstance on the original asset that this instance was created from");
|
"This is itself an instance. Call getInstance on the original asset that this instance was created from");
|
||||||
}
|
}
|
||||||
var instance = SceneAsset_getInstance(pointer, index);
|
var instance = SceneAsset_getInstance(asset, index);
|
||||||
if (instance == nullptr) {
|
if (instance == nullptr) {
|
||||||
throw Exception("No instance available at index $index");
|
throw Exception("No instance available at index $index");
|
||||||
}
|
}
|
||||||
return FFIAsset(
|
return FFIAsset(instance, app);
|
||||||
instance, sceneManager, engine, _unlitMaterialProvider, viewer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -100,7 +77,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneAsset_createInstanceRenderThread(
|
SceneAsset_createInstanceRenderThread(
|
||||||
pointer,
|
asset,
|
||||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
||||||
materialInstances?.length ?? 0,
|
materialInstances?.length ?? 0,
|
||||||
cb);
|
cb);
|
||||||
@@ -108,8 +85,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
if (created == FILAMENT_ASSET_ERROR) {
|
if (created == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("Failed to create instance");
|
throw Exception("Failed to create instance");
|
||||||
}
|
}
|
||||||
return FFIAsset(
|
return FFIAsset(created, app);
|
||||||
created, sceneManager, engine, _unlitMaterialProvider, viewer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -117,7 +93,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<int> getInstanceCount() async {
|
Future<int> getInstanceCount() async {
|
||||||
return SceneAsset_getInstanceCount(pointer);
|
return SceneAsset_getInstanceCount(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -127,8 +103,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
Future<List<ThermionAsset>> getInstances() async {
|
Future<List<ThermionAsset>> getInstances() async {
|
||||||
var count = await getInstanceCount();
|
var count = await getInstanceCount();
|
||||||
final result = List<ThermionAsset>.generate(count, (i) {
|
final result = List<ThermionAsset>.generate(count, (i) {
|
||||||
return FFIAsset(SceneAsset_getInstance(pointer, i), sceneManager, engine,
|
return FFIAsset(SceneAsset_getInstance(asset, i), app);
|
||||||
_unlitMaterialProvider, viewer);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -139,13 +114,14 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeStencilHighlight() async {
|
Future removeStencilHighlight() async {
|
||||||
if (_highlight != null) {
|
throw UnimplementedError();
|
||||||
SceneManager_removeFromScene(sceneManager, _highlight!.entity);
|
// if (_highlight != null) {
|
||||||
final childEntities = await _highlight!.getChildEntities();
|
// SceneManager_removeFromScene(sceneManager, _highlight!.entity);
|
||||||
for (final child in childEntities) {
|
// final childEntities = await _highlight!.getChildEntities();
|
||||||
SceneManager_removeFromScene(sceneManager, child);
|
// for (final child in childEntities) {
|
||||||
}
|
// SceneManager_removeFromScene(sceneManager, child);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -165,8 +141,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
var sourceMaterialInstance = FFIMaterialInstance(
|
var sourceMaterialInstance = FFIMaterialInstance(
|
||||||
RenderableManager_getMaterialInstanceAt(
|
RenderableManager_getMaterialInstanceAt(
|
||||||
renderableManager, targetEntity, 0),
|
app.renderableManager, targetEntity, 0), app);
|
||||||
sceneManager);
|
|
||||||
|
|
||||||
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
||||||
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
||||||
@@ -179,10 +154,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
await withPointerCallback<TMaterialInstance>((cb) {
|
await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
final key = Struct.create<TMaterialKey>();
|
final key = Struct.create<TMaterialKey>();
|
||||||
MaterialProvider_createMaterialInstanceRenderThread(
|
MaterialProvider_createMaterialInstanceRenderThread(
|
||||||
_unlitMaterialProvider, key.address, cb);
|
app.ubershaderMaterialProvider, key.address, cb);
|
||||||
});
|
});
|
||||||
final highlightMaterialInstance =
|
final highlightMaterialInstance =
|
||||||
FFIMaterialInstance(materialInstancePtr, sceneManager);
|
FFIMaterialInstance(materialInstancePtr, app);
|
||||||
await highlightMaterialInstance
|
await highlightMaterialInstance
|
||||||
.setStencilCompareFunction(SamplerCompareFunction.NE);
|
.setStencilCompareFunction(SamplerCompareFunction.NE);
|
||||||
await highlightMaterialInstance.setStencilReferenceValue(1);
|
await highlightMaterialInstance.setStencilReferenceValue(1);
|
||||||
@@ -197,10 +172,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
_highlight = highlightInstance;
|
_highlight = highlightInstance;
|
||||||
|
|
||||||
await highlightMaterialInstance.setStencilReferenceValue(1);
|
await highlightMaterialInstance.setStencilReferenceValue(1);
|
||||||
RenderableManager_setPriority(renderableManager, targetEntity, 0);
|
RenderableManager_setPriority(app.renderableManager, targetEntity, 0);
|
||||||
final transformManager = Engine_getTransformManager(engine);
|
|
||||||
TransformManager_setParent(
|
TransformManager_setParent(
|
||||||
transformManager, _highlight!.entity, entity, false);
|
app.transformManager, _highlight!.entity, entity, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetHighlightEntity = _highlight!.entity;
|
var targetHighlightEntity = _highlight!.entity;
|
||||||
@@ -210,35 +185,17 @@ class FFIAsset extends ThermionAsset {
|
|||||||
targetHighlightEntity = highlightChildEntities[entityIndex!];
|
targetHighlightEntity = highlightChildEntities[entityIndex!];
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableManager_setPriority(renderableManager, targetHighlightEntity, 7);
|
RenderableManager_setPriority(
|
||||||
|
app.renderableManager, targetHighlightEntity, 7);
|
||||||
|
|
||||||
SceneManager_addToScene(sceneManager, targetHighlightEntity);
|
throw UnimplementedError();
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
@override
|
|
||||||
Future addToScene() async {
|
|
||||||
SceneAsset_addToScene(pointer, SceneManager_getScene(sceneManager));
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
@override
|
|
||||||
Future removeFromScene() async {
|
|
||||||
SceneManager_removeFromScene(sceneManager, entity);
|
|
||||||
for (final child in await getChildEntities()) {
|
|
||||||
SceneManager_removeFromScene(sceneManager, child);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FFIAsset? boundingBoxAsset;
|
FFIAsset? boundingBoxAsset;
|
||||||
|
|
||||||
Future<v64.Aabb3> getBoundingBox() async {
|
Future<v64.Aabb3> getBoundingBox() async {
|
||||||
final entities = <ThermionEntity>[];
|
final entities = <ThermionEntity>[];
|
||||||
if (RenderableManager_isRenderable(renderableManager, entity)) {
|
if (RenderableManager_isRenderable(app.renderableManager, entity)) {
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
} else {
|
} else {
|
||||||
entities.addAll(await getChildEntities());
|
entities.addAll(await getChildEntities());
|
||||||
@@ -247,7 +204,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
var boundingBox = v64.Aabb3();
|
var boundingBox = v64.Aabb3();
|
||||||
|
|
||||||
for (final entity in entities) {
|
for (final entity in entities) {
|
||||||
final aabb3 = SceneManager_getRenderableBoundingBox(sceneManager, entity);
|
final aabb3 = RenderableManager_getAabb(app.renderableManager, entity);
|
||||||
final entityBB = v64.Aabb3.centerAndHalfExtents(
|
final entityBB = v64.Aabb3.centerAndHalfExtents(
|
||||||
v64.Vector3(aabb3.centerX, aabb3.centerY, aabb3.centerZ),
|
v64.Vector3(aabb3.centerX, aabb3.centerY, aabb3.centerZ),
|
||||||
v64.Vector3(aabb3.halfExtentX, aabb3.halfExtentY, aabb3.halfExtentZ),
|
v64.Vector3(aabb3.halfExtentX, aabb3.halfExtentY, aabb3.halfExtentZ),
|
||||||
@@ -263,7 +220,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
@override
|
@override
|
||||||
Future<void> setBoundingBoxVisibility(bool visible) async {
|
Future<void> setBoundingBoxVisibility(bool visible) async {
|
||||||
if (boundingBoxAsset == null) {
|
if (boundingBoxAsset == null) {
|
||||||
final boundingBox = await SceneAsset_getBoundingBox(pointer);
|
final boundingBox = await SceneAsset_getBoundingBox(asset);
|
||||||
|
|
||||||
final min = [
|
final min = [
|
||||||
boundingBox.centerX - boundingBox.halfExtentX,
|
boundingBox.centerX - boundingBox.halfExtentX,
|
||||||
@@ -323,10 +280,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
await withPointerCallback<TMaterialInstance>((cb) {
|
await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
final key = Struct.create<TMaterialKey>();
|
final key = Struct.create<TMaterialKey>();
|
||||||
MaterialProvider_createMaterialInstanceRenderThread(
|
MaterialProvider_createMaterialInstanceRenderThread(
|
||||||
_unlitMaterialProvider, key.address, cb);
|
app.ubershaderMaterialProvider, key.address, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
final material = FFIMaterialInstance(materialInstancePtr, sceneManager);
|
final material = FFIMaterialInstance(materialInstancePtr, app);
|
||||||
await material.setParameterFloat4(
|
await material.setParameterFloat4(
|
||||||
"baseColorFactor", 1.0, 1.0, 0.0, 1.0); // Yellow wireframe
|
"baseColorFactor", 1.0, 1.0, 0.0, 1.0); // Yellow wireframe
|
||||||
|
|
||||||
@@ -337,23 +294,25 @@ class FFIAsset extends ThermionAsset {
|
|||||||
primitiveType: PrimitiveType.LINES,
|
primitiveType: PrimitiveType.LINES,
|
||||||
);
|
);
|
||||||
|
|
||||||
boundingBoxAsset = await viewer.createGeometry(
|
throw UnimplementedError();
|
||||||
geometry,
|
|
||||||
materialInstances: [material],
|
|
||||||
keepData: false,
|
|
||||||
) as FFIAsset;
|
|
||||||
|
|
||||||
await viewer.setCastShadows(boundingBoxAsset!.entity, false);
|
// boundingBoxAsset = await viewer.createGeometry(
|
||||||
await viewer.setReceiveShadows(boundingBoxAsset!.entity, false);
|
// geometry,
|
||||||
|
// materialInstances: [material],
|
||||||
|
// keepData: false,
|
||||||
|
// ) as FFIAsset;
|
||||||
|
|
||||||
TransformManager_setParent(Engine_getTransformManager(engine),
|
await boundingBoxAsset!.setCastShadows(false);
|
||||||
|
await boundingBoxAsset!.setReceiveShadows(false);
|
||||||
|
|
||||||
|
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
||||||
boundingBoxAsset!.entity, entity, false);
|
boundingBoxAsset!.entity, entity, false);
|
||||||
}
|
}
|
||||||
if (visible) {
|
// if (visible) {
|
||||||
await boundingBoxAsset!.addToScene();
|
// await boundingBoxAsset!.addToScene();
|
||||||
} else {
|
// } else {
|
||||||
await boundingBoxAsset!.removeFromScene();
|
// await boundingBoxAsset!.removeFromScene();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -365,7 +324,25 @@ class FFIAsset extends ThermionAsset {
|
|||||||
final entities = <ThermionEntity>[entity, ...childEntities];
|
final entities = <ThermionEntity>[entity, ...childEntities];
|
||||||
for (final entity in entities) {
|
for (final entity in entities) {
|
||||||
RenderableManager_setMaterialInstanceAt(
|
RenderableManager_setMaterialInstanceAt(
|
||||||
Engine_getRenderableManager(engine), entity, 0, instance.pointer);
|
Engine_getRenderableManager(app.engine), entity, 0, instance.pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future setCastShadows(bool castShadows) async {
|
||||||
|
RenderableManager_setCastShadows(
|
||||||
|
app.renderableManager, this.entity, castShadows);
|
||||||
|
for (final entity in await this.getChildEntities()) {
|
||||||
|
RenderableManager_setCastShadows(
|
||||||
|
app.renderableManager, entity, castShadows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future setReceiveShadows(bool receiveShadows) async {
|
||||||
|
RenderableManager_setReceiveShadows(
|
||||||
|
app.renderableManager, this.entity, receiveShadows);
|
||||||
|
for (final entity in await this.getChildEntities()) {
|
||||||
|
RenderableManager_setReceiveShadows(
|
||||||
|
app.renderableManager, entity, receiveShadows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final Pointer<TRenderableManager> renderableManager;
|
final Pointer<TRenderableManager> renderableManager;
|
||||||
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
|
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
|
||||||
final Pointer<TRenderTicker> renderTicker;
|
final Pointer<TRenderTicker> renderTicker;
|
||||||
|
final Pointer<TNameComponentManager> nameComponentManager;
|
||||||
|
|
||||||
FFIFilamentApp(
|
FFIFilamentApp(
|
||||||
this.engine,
|
this.engine,
|
||||||
@@ -36,7 +37,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
this.lightManager,
|
this.lightManager,
|
||||||
this.renderableManager,
|
this.renderableManager,
|
||||||
this.ubershaderMaterialProvider,
|
this.ubershaderMaterialProvider,
|
||||||
this.renderTicker)
|
this.renderTicker,
|
||||||
|
this.nameComponentManager)
|
||||||
: super(
|
: super(
|
||||||
engine: engine,
|
engine: engine,
|
||||||
gltfAssetLoader: gltfAssetLoader,
|
gltfAssetLoader: gltfAssetLoader,
|
||||||
@@ -76,7 +78,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final renderableManager = Engine_getRenderableManager(engine);
|
final renderableManager = Engine_getRenderableManager(engine);
|
||||||
|
|
||||||
final renderTicker = await withPointerCallback<TRenderTicker>(
|
final renderTicker = await withPointerCallback<TRenderTicker>(
|
||||||
(cb) => RenderTicker_create());
|
(cb) => RenderTicker_create(renderer));
|
||||||
|
|
||||||
|
final nameComponentManager = NameComponentManager_create();
|
||||||
|
|
||||||
_instance = FFIFilamentApp(
|
_instance = FFIFilamentApp(
|
||||||
engine,
|
engine,
|
||||||
@@ -86,7 +90,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
transformManager,
|
transformManager,
|
||||||
lightManager,
|
lightManager,
|
||||||
renderableManager,
|
renderableManager,
|
||||||
ubershaderMaterialProvider);
|
ubershaderMaterialProvider,
|
||||||
|
renderTicker, nameComponentManager);
|
||||||
}
|
}
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
class FFIMaterial extends Material {
|
class FFIMaterial extends Material {
|
||||||
final Pointer<TEngine> engine;
|
final FFIFilamentApp app;
|
||||||
final Pointer<TSceneManager> sceneManager;
|
|
||||||
final Pointer<TMaterial> pointer;
|
final Pointer<TMaterial> pointer;
|
||||||
|
|
||||||
FFIMaterial(this.pointer, this.engine, this.sceneManager);
|
FFIMaterial(this.pointer, this.app);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MaterialInstance> createInstance() async {
|
Future<MaterialInstance> createInstance() async {
|
||||||
var ptr = await withPointerCallback<TMaterialInstance>((cb) {
|
var ptr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
Material_createInstanceRenderThread(pointer, cb);
|
Material_createInstanceRenderThread(pointer, cb);
|
||||||
});
|
});
|
||||||
return FFIMaterialInstance(ptr, sceneManager);
|
return FFIMaterialInstance(ptr, this.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future dispose() async {
|
Future destroy() async {
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Engine_destroyMaterialRenderThread(engine, pointer, cb);
|
Engine_destroyMaterialRenderThread(app.engine, pointer, cb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +35,9 @@ class FFIMaterial extends Material {
|
|||||||
|
|
||||||
class FFIMaterialInstance extends MaterialInstance {
|
class FFIMaterialInstance extends MaterialInstance {
|
||||||
final Pointer<TMaterialInstance> pointer;
|
final Pointer<TMaterialInstance> pointer;
|
||||||
final Pointer<TSceneManager> sceneManager;
|
final FFIFilamentApp app;
|
||||||
|
|
||||||
FFIMaterialInstance(this.pointer, this.sceneManager) {
|
FFIMaterialInstance(this.pointer, this.app) {
|
||||||
if (pointer == nullptr) {
|
if (pointer == nullptr) {
|
||||||
throw Exception("MaterialInstance not found");
|
throw Exception("MaterialInstance not found");
|
||||||
}
|
}
|
||||||
@@ -169,10 +169,9 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
MaterialInstance_setStencilWriteMask(pointer, mask);
|
MaterialInstance_setStencilWriteMask(pointer, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future dispose() async {
|
Future destroy() async {
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
SceneManager_destroyMaterialInstanceRenderThread(
|
Engine_destroyMaterialInstanceRenderThread(app.engine, this.pointer, cb);
|
||||||
sceneManager, pointer, cb);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
|
|
||||||
import 'package:thermion_dart/src/viewer/src/shared_types/scene.dart';
|
import 'package:thermion_dart/src/viewer/src/shared_types/scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
|
|
||||||
import 'callbacks.dart';
|
import 'callbacks.dart';
|
||||||
import 'ffi_camera.dart';
|
|
||||||
|
|
||||||
class FFIScene extends Scene {
|
class FFIScene extends Scene {
|
||||||
final Pointer<TScene> scene;
|
final Pointer<TScene> scene;
|
||||||
@@ -12,8 +11,15 @@ class FFIScene extends Scene {
|
|||||||
|
|
||||||
FFIRenderTarget? renderTarget;
|
FFIRenderTarget? renderTarget;
|
||||||
|
|
||||||
FFIScene(this.scene, this.app) {
|
FFIScene(this.scene, this.app) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future add(covariant FFIAsset asset) async {
|
||||||
|
SceneAsset_addToScene(asset.asset, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future remove(covariant FFIAsset asset) async {
|
||||||
|
SceneAsset_removeFromScene(asset.asset, scene);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,14 +327,22 @@ external void LightManager_setDirection(
|
|||||||
double z,
|
double z,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<TLightManager>, EntityId, ffi.Int)>(
|
@ffi.Native<ffi.Int Function(ffi.Pointer<TLightManager>, ffi.UnsignedInt)>(
|
||||||
isLeaf: true)
|
symbol: "LightManager_createLight", isLeaf: true)
|
||||||
external int LightManager_createLight(
|
external int _LightManager_createLight(
|
||||||
ffi.Pointer<TLightManager> tLightManager,
|
ffi.Pointer<TLightManager> tLightManager,
|
||||||
int entity,
|
int tLightTtype,
|
||||||
int type,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int LightManager_createLight(
|
||||||
|
ffi.Pointer<TLightManager> tLightManager,
|
||||||
|
TLightType tLightTtype,
|
||||||
|
) =>
|
||||||
|
_LightManager_createLight(
|
||||||
|
tLightManager,
|
||||||
|
tLightTtype.value,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TLightManager>, EntityId)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TLightManager>, EntityId)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void LightManager_destroyLight(
|
external void LightManager_destroyLight(
|
||||||
@@ -342,15 +350,12 @@ external void LightManager_destroyLight(
|
|||||||
int entity,
|
int entity,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TLightManager>, EntityId, ffi.Float)>(
|
||||||
ffi.Void Function(ffi.Pointer<TLightManager>, EntityId, ffi.Double,
|
isLeaf: true)
|
||||||
ffi.Double, ffi.Double)>(isLeaf: true)
|
|
||||||
external void LightManager_setColor(
|
external void LightManager_setColor(
|
||||||
ffi.Pointer<TLightManager> tLightManager,
|
ffi.Pointer<TLightManager> tLightManager,
|
||||||
int entity,
|
int entity,
|
||||||
double r,
|
double colorTemperature,
|
||||||
double g,
|
|
||||||
double b,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
@@ -995,6 +1000,9 @@ external void View_pick(
|
|||||||
PickCallback callback,
|
PickCallback callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Pointer<TNameComponentManager> Function()>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TNameComponentManager> NameComponentManager_create();
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<ffi.Char> Function(
|
ffi.Pointer<ffi.Char> Function(
|
||||||
ffi.Pointer<TNameComponentManager>, EntityId)>(isLeaf: true)
|
ffi.Pointer<TNameComponentManager>, EntityId)>(isLeaf: true)
|
||||||
@@ -1003,6 +1011,14 @@ external ffi.Pointer<ffi.Char> NameComponentManager_getName(
|
|||||||
int entity,
|
int entity,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TIndirectLight>, ffi.Pointer<ffi.Double>)>(isLeaf: true)
|
||||||
|
external void IndirectLight_setRotation(
|
||||||
|
ffi.Pointer<TIndirectLight> tIndirectLight,
|
||||||
|
ffi.Pointer<ffi.Double> rotation,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TGizmo>, ffi.Uint32, ffi.Uint32,
|
ffi.Void Function(ffi.Pointer<TGizmo>, ffi.Uint32, ffi.Uint32,
|
||||||
GizmoPickCallback)>(isLeaf: true)
|
GizmoPickCallback)>(isLeaf: true)
|
||||||
@@ -1067,6 +1083,12 @@ external void Scene_addEntity(
|
|||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, EntityId)>(isLeaf: true)
|
||||||
|
external void Scene_removeEntity(
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
int entityId,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, ffi.Pointer<TSkybox>)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, ffi.Pointer<TSkybox>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void Scene_setSkybox(
|
external void Scene_setSkybox(
|
||||||
@@ -1383,12 +1405,26 @@ external void Renderer_setFrameInterval(
|
|||||||
int interval,
|
int interval,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<ffi.Pointer<TRenderTicker> Function(ffi.Pointer<TRenderer>)>(
|
||||||
ffi.Pointer<TRenderTicker> Function(
|
isLeaf: true)
|
||||||
ffi.Pointer<TRenderer>, ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
|
||||||
external ffi.Pointer<TRenderTicker> RenderTicker_create(
|
external ffi.Pointer<TRenderTicker> RenderTicker_create(
|
||||||
ffi.Pointer<TRenderer> tRenderer,
|
ffi.Pointer<TRenderer> tRenderer,
|
||||||
ffi.Pointer<TSceneManager> tSceneManager,
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||||
|
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||||
|
external void RenderTicker_addAnimationManager(
|
||||||
|
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||||
|
ffi.Pointer<TAnimationManager> tAnimationManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||||
|
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||||
|
external void RenderTicker_removeAnimationManager(
|
||||||
|
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||||
|
ffi.Pointer<TAnimationManager> tAnimationManager,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>, ffi.Uint64)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>, ffi.Uint64)>(
|
||||||
@@ -1421,6 +1457,22 @@ external void RenderTicker_renderRenderThread(
|
|||||||
int frameTimeInNanos,
|
int frameTimeInNanos,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TEngine>,
|
||||||
|
ffi.Pointer<TScene>,
|
||||||
|
ffi.Pointer<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TAnimationManager>)>>)>(isLeaf: true)
|
||||||
|
external void AnimationManager_createRenderThread(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
ffi.Pointer<
|
||||||
|
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TAnimationManager>)>>
|
||||||
|
onComplete,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Int,
|
ffi.Int,
|
||||||
@@ -1549,6 +1601,15 @@ external void Engine_destroyMaterialRenderThread(
|
|||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TMaterialInstance>,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||||
|
external void Engine_destroyMaterialInstanceRenderThread(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ffi.Pointer<TMaterialInstance> tMaterialInstance,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TSkybox>,
|
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TSkybox>,
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||||
@@ -3182,6 +3243,13 @@ external bool RenderableManager_getFogEnabled(
|
|||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<Aabb3 Function(ffi.Pointer<TRenderableManager>, EntityId)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external Aabb3 RenderableManager_getAabb(
|
||||||
|
ffi.Pointer<TRenderableManager> tRenderableManager,
|
||||||
|
int entityId,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<TEngine> Function(
|
ffi.Pointer<TEngine> Function(
|
||||||
ffi.UnsignedInt,
|
ffi.UnsignedInt,
|
||||||
@@ -3324,6 +3392,14 @@ external void Engine_destroyMaterial(
|
|||||||
ffi.Pointer<TMaterial> tMaterial,
|
ffi.Pointer<TMaterial> tMaterial,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TEngine>, ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
|
||||||
|
external void Engine_destroyMaterialInstance(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ffi.Pointer<TMaterialInstance> tMaterialInstance,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||||
external ffi.Pointer<TScene> Engine_createScene(
|
external ffi.Pointer<TScene> Engine_createScene(
|
||||||
ffi.Pointer<TEngine> tEngine,
|
ffi.Pointer<TEngine> tEngine,
|
||||||
@@ -3401,6 +3477,44 @@ external ffi.Pointer<TSceneAsset> SceneAsset_createGeometry(
|
|||||||
int materialInstanceCount,
|
int materialInstanceCount,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Pointer<TSceneAsset> Function(
|
||||||
|
ffi.Pointer<TGltfAssetLoader>,
|
||||||
|
ffi.Pointer<TGltfResourceLoader>,
|
||||||
|
ffi.Pointer<TEngine>,
|
||||||
|
ffi.Pointer<TNameComponentManager>,
|
||||||
|
ffi.Pointer<ffi.Uint8>,
|
||||||
|
ffi.Size,
|
||||||
|
ffi.Size)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TSceneAsset> SceneAsset_loadGlb(
|
||||||
|
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
|
||||||
|
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ffi.Pointer<TNameComponentManager> tNameComponentManager,
|
||||||
|
ffi.Pointer<ffi.Uint8> data,
|
||||||
|
int length,
|
||||||
|
int numInstances,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Pointer<TSceneAsset> Function(
|
||||||
|
ffi.Pointer<TGltfAssetLoader>,
|
||||||
|
ffi.Pointer<TGltfResourceLoader>,
|
||||||
|
ffi.Pointer<TEngine>,
|
||||||
|
ffi.Pointer<TNameComponentManager>,
|
||||||
|
ffi.Pointer<ffi.Uint8>,
|
||||||
|
ffi.Size,
|
||||||
|
ffi.Size)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TSceneAsset> SceneAsset_loadGltf(
|
||||||
|
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
|
||||||
|
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ffi.Pointer<TNameComponentManager> tNameComponentManager,
|
||||||
|
ffi.Pointer<ffi.Uint8> data,
|
||||||
|
int length,
|
||||||
|
int numInstances,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void SceneAsset_addToScene(
|
external void SceneAsset_addToScene(
|
||||||
@@ -3408,6 +3522,13 @@ external void SceneAsset_addToScene(
|
|||||||
ffi.Pointer<TScene> tScene,
|
ffi.Pointer<TScene> tScene,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void SceneAsset_removeFromScene(
|
||||||
|
ffi.Pointer<TSceneAsset> tSceneAsset,
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<EntityId Function(ffi.Pointer<TSceneAsset>)>(isLeaf: true)
|
@ffi.Native<EntityId Function(ffi.Pointer<TSceneAsset>)>(isLeaf: true)
|
||||||
external int SceneAsset_getEntity(
|
external int SceneAsset_getEntity(
|
||||||
ffi.Pointer<TSceneAsset> tSceneAsset,
|
ffi.Pointer<TSceneAsset> tSceneAsset,
|
||||||
@@ -3465,6 +3586,12 @@ external Aabb3 SceneAsset_getBoundingBox(
|
|||||||
ffi.Pointer<TSceneAsset> asset,
|
ffi.Pointer<TSceneAsset> asset,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Pointer<TAnimationManager> Function(ffi.Pointer<TEngine>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external ffi.Pointer<TAnimationManager> AnimationManager_create(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void AnimationManager_addAnimationComponent(
|
external void AnimationManager_addAnimationComponent(
|
||||||
@@ -4131,6 +4258,26 @@ enum TTransparencyMode {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TLightType {
|
||||||
|
LIGHT_TYPE_SUN(0),
|
||||||
|
LIGHT_TYPE_DIRECTIONAL(1),
|
||||||
|
LIGHT_TYPE_POINT(2),
|
||||||
|
LIGHT_TYPE_FOCUSED_SPOT(3),
|
||||||
|
LIGHT_TYPE_SPOT(4);
|
||||||
|
|
||||||
|
final int value;
|
||||||
|
const TLightType(this.value);
|
||||||
|
|
||||||
|
static TLightType fromValue(int value) => switch (value) {
|
||||||
|
0 => LIGHT_TYPE_SUN,
|
||||||
|
1 => LIGHT_TYPE_DIRECTIONAL,
|
||||||
|
2 => LIGHT_TYPE_POINT,
|
||||||
|
3 => LIGHT_TYPE_FOCUSED_SPOT,
|
||||||
|
4 => LIGHT_TYPE_SPOT,
|
||||||
|
_ => throw ArgumentError("Unknown value for TLightType: $value"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
typedef EntityId = ffi.Int32;
|
typedef EntityId = ffi.Int32;
|
||||||
typedef DartEntityId = int;
|
typedef DartEntityId = int;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import 'callbacks.dart';
|
|||||||
import 'ffi_camera.dart';
|
import 'ffi_camera.dart';
|
||||||
import 'ffi_view.dart';
|
import 'ffi_view.dart';
|
||||||
|
|
||||||
|
const FILAMENT_ASSET_ERROR = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -37,29 +39,30 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
|
|
||||||
late final FFIFilamentApp app;
|
late final FFIFilamentApp app;
|
||||||
late final FFIRenderTarget? renderTarget;
|
late final FFIRenderTarget? renderTarget;
|
||||||
|
late final Future<Uint8List> Function(String path) assetLoader;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
ThermionViewerFFI(this.app, {this.renderTarget}) {
|
ThermionViewerFFI(this.assetLoader, this.app, {this.renderTarget}) {
|
||||||
_onPickResultCallable =
|
_onPickResultCallable =
|
||||||
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
|
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
|
||||||
|
|
||||||
_initialize();
|
_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
// ///
|
||||||
///
|
// ///
|
||||||
///
|
// ///
|
||||||
Future<RenderTarget> createRenderTarget(int width, int height,
|
// Future<RenderTarget> createRenderTarget(int width, int height,
|
||||||
{covariant FFITexture? color, covariant FFITexture? depth}) async {
|
// {covariant FFITexture? color, covariant FFITexture? depth}) async {
|
||||||
final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
|
// final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
|
||||||
RenderTarget_createRenderThread(app.engine, width, height,
|
// RenderTarget_createRenderThread(app.engine, width, height,
|
||||||
color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
|
// color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
|
||||||
});
|
// });
|
||||||
|
|
||||||
return FFIRenderTarget(renderTarget, app);
|
// return FFIRenderTarget(renderTarget, app);
|
||||||
}
|
// }
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -95,6 +98,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
late final FFIView view;
|
late final FFIView view;
|
||||||
late final FFIScene scene;
|
late final FFIScene scene;
|
||||||
late final FFICamera camera;
|
late final FFICamera camera;
|
||||||
|
late final Pointer<TAnimationManager> animationManager;
|
||||||
|
|
||||||
Future _initialize() async {
|
Future _initialize() async {
|
||||||
_logger.info("Initializing ThermionViewerFFI");
|
_logger.info("Initializing ThermionViewerFFI");
|
||||||
@@ -111,6 +115,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
if (renderTarget != null) {
|
if (renderTarget != null) {
|
||||||
await view.setRenderTarget(renderTarget);
|
await view.setRenderTarget(renderTarget);
|
||||||
}
|
}
|
||||||
|
animationManager = await withPointerCallback<TAnimationManager>((cb) =>
|
||||||
|
AnimationManager_createRenderThread(app.engine, scene.scene, cb));
|
||||||
|
|
||||||
|
RenderTicker_addAnimationManager(app.renderTicker, animationManager);
|
||||||
this._initialized.complete(true);
|
this._initialized.complete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,79 +144,78 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future render() async {
|
Future render() async {
|
||||||
RenderTicker_renderRenderThread(app.renderTicker, 0);
|
RenderTicker_renderRenderThread(app.renderTicker, 0);
|
||||||
// Viewer_renderRenderThread(_viewer!, view.view, swapChain.swapChain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
// ///
|
||||||
///
|
// ///
|
||||||
///
|
// ///
|
||||||
@override
|
// @override
|
||||||
Future<Uint8List> capture() async {
|
// Future<Uint8List> capture() async {
|
||||||
final fence = await withPointerCallback<TFence>((cb) {
|
// final fence = await withPointerCallback<TFence>((cb) {
|
||||||
Engine_createFenceRenderThread(app.engine!, cb);
|
// Engine_createFenceRenderThread(app.engine!, cb);
|
||||||
});
|
// });
|
||||||
|
|
||||||
var pixelBuffers = <Uint8List>[];
|
// var pixelBuffers = <Uint8List>[];
|
||||||
|
|
||||||
for (final entry in targets) {
|
// for (final entry in targets) {
|
||||||
final view = entry.view as FFIView;
|
// final view = entry.view as FFIView;
|
||||||
var swapChain = entry.swapChain as FFISwapChain?;
|
// var swapChain = entry.swapChain as FFISwapChain?;
|
||||||
final renderTarget = entry.renderTarget as FFIRenderTarget?;
|
// final renderTarget = entry.renderTarget as FFIRenderTarget?;
|
||||||
final vp = await view.getViewport();
|
// final vp = await view.getViewport();
|
||||||
final length = vp.width * vp.height * 4;
|
// final length = vp.width * vp.height * 4;
|
||||||
|
|
||||||
await withBoolCallback((cb) {
|
// await withBoolCallback((cb) {
|
||||||
Renderer_beginFrameRenderThread(renderer,
|
// Renderer_beginFrameRenderThread(renderer,
|
||||||
swapChain?.swapChain ?? Viewer_getSwapChainAt(_viewer!, 0), 0, cb);
|
// swapChain?.swapChain ?? Viewer_getSwapChainAt(_viewer!, 0), 0, cb);
|
||||||
});
|
// });
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
|
||||||
Renderer_renderRenderThread(renderer, view.view, cb);
|
|
||||||
});
|
|
||||||
final out = Uint8List(length);
|
|
||||||
await withVoidCallback((cb) {
|
|
||||||
Renderer_readPixelsRenderThread(
|
|
||||||
renderer,
|
|
||||||
view.view,
|
|
||||||
renderTarget!.renderTarget,
|
|
||||||
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
|
||||||
TPixelDataType.PIXELDATATYPE_UBYTE,
|
|
||||||
out.address,
|
|
||||||
cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
pixelBuffers.add(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
|
||||||
Renderer_endFrameRenderThread(renderer, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
|
||||||
Engine_flushAndWaitRenderThead(app.engine!, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
|
||||||
Engine_destroyFenceRenderThread(app.engine!, fence, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
// await withVoidCallback((cb) {
|
// await withVoidCallback((cb) {
|
||||||
// if (renderTarget != null) {
|
// Renderer_renderRenderThread(renderer, view.view, cb);
|
||||||
// Viewer_captureRenderTargetRenderThread(
|
|
||||||
// _viewer!,
|
|
||||||
// view!.view,
|
|
||||||
// swapChain!.swapChain,
|
|
||||||
// renderTarget.renderTarget,
|
|
||||||
// out.address,
|
|
||||||
// useFence,
|
|
||||||
// cb);
|
|
||||||
// } else {
|
|
||||||
// Viewer_captureRenderThread(_viewer!, view!.view, swapChain!.swapChain,
|
|
||||||
// out.address, useFence, cb);
|
|
||||||
// }
|
|
||||||
// });
|
// });
|
||||||
return pixelBuffers;
|
// final out = Uint8List(length);
|
||||||
}
|
// await withVoidCallback((cb) {
|
||||||
|
// Renderer_readPixelsRenderThread(
|
||||||
|
// renderer,
|
||||||
|
// view.view,
|
||||||
|
// renderTarget!.renderTarget,
|
||||||
|
// TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||||
|
// TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||||
|
// out.address,
|
||||||
|
// cb);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// pixelBuffers.add(out);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await withVoidCallback((cb) {
|
||||||
|
// Renderer_endFrameRenderThread(renderer, cb);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await withVoidCallback((cb) {
|
||||||
|
// Engine_flushAndWaitRenderThead(app.engine!, cb);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await withVoidCallback((cb) {
|
||||||
|
// Engine_destroyFenceRenderThread(app.engine!, fence, cb);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // await withVoidCallback((cb) {
|
||||||
|
// // if (renderTarget != null) {
|
||||||
|
// // Viewer_captureRenderTargetRenderThread(
|
||||||
|
// // _viewer!,
|
||||||
|
// // view!.view,
|
||||||
|
// // swapChain!.swapChain,
|
||||||
|
// // renderTarget.renderTarget,
|
||||||
|
// // out.address,
|
||||||
|
// // useFence,
|
||||||
|
// // cb);
|
||||||
|
// // } else {
|
||||||
|
// // Viewer_captureRenderThread(_viewer!, view!.view, swapChain!.swapChain,
|
||||||
|
// // out.address, useFence, cb);
|
||||||
|
// // }
|
||||||
|
// // });
|
||||||
|
// return pixelBuffers;
|
||||||
|
// }
|
||||||
|
|
||||||
double _msPerFrame = 1000.0 / 60.0;
|
double _msPerFrame = 1000.0 / 60.0;
|
||||||
|
|
||||||
@@ -225,7 +232,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future setFrameRate(int framerate) async {
|
Future setFrameRate(int framerate) async {
|
||||||
_msPerFrame = 1000.0 / framerate;
|
_msPerFrame = 1000.0 / framerate;
|
||||||
set_frame_interval_render_thread(_viewer!, _msPerFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final _onDispose = <Future Function()>[];
|
final _onDispose = <Future Function()>[];
|
||||||
@@ -238,20 +244,14 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future dispose() async {
|
Future dispose() async {
|
||||||
if (_viewer == null) {
|
|
||||||
throw Exception("Viewer has already been disposed.");
|
|
||||||
}
|
|
||||||
_disposing = true;
|
_disposing = true;
|
||||||
await setRendering(false);
|
await setRendering(false);
|
||||||
await destroyAssets();
|
await destroyAssets();
|
||||||
for (final mInstance in _materialInstances) {
|
for (final mInstance in _materialInstances) {
|
||||||
await mInstance.dispose();
|
await mInstance.destroy();
|
||||||
}
|
}
|
||||||
await destroyLights();
|
await destroyLights();
|
||||||
|
|
||||||
_sceneManager = null;
|
|
||||||
_viewer = null;
|
|
||||||
|
|
||||||
for (final callback in _onDispose) {
|
for (final callback in _onDispose) {
|
||||||
await callback.call();
|
await callback.call();
|
||||||
}
|
}
|
||||||
@@ -310,34 +310,39 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future loadSkybox(String skyboxPath) async {
|
Future loadSkybox(String skyboxPath) async {
|
||||||
final pathPtr = skyboxPath.toNativeUtf8(allocator: allocator).cast<Char>();
|
var data = await _loadAsset(skyboxPath);
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
skybox = await withPointerCallback<TSkybox>((cb) {
|
||||||
Viewer_loadSkyboxRenderThread(_viewer!, pathPtr, cb);
|
Engine_buildSkyboxRenderThread(
|
||||||
|
app.engine, data.address, data.length, cb, nullptr);
|
||||||
});
|
});
|
||||||
|
Scene_setSkybox(scene.scene, skybox!);
|
||||||
allocator.free(pathPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
Future<Uint8List> _loadAsset(String path) async {
|
||||||
///
|
if (path.startsWith("file://")) {
|
||||||
///
|
return File(path.replaceAll("file://", "")).readAsBytesSync();
|
||||||
@override
|
|
||||||
Future createIbl(double r, double g, double b, double intensity) async {
|
|
||||||
create_ibl(_viewer!, r, g, b, intensity);
|
|
||||||
}
|
}
|
||||||
|
if (path.startsWith("asset://")) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pointer<TIndirectLight>? indirectLight;
|
||||||
|
Pointer<TSkybox>? skybox;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
||||||
final pathPtr =
|
var data = await _loadAsset(lightingPath);
|
||||||
lightingPath.toNativeUtf8(allocator: allocator).cast<Char>();
|
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
|
||||||
|
Engine_buildIndirectLightRenderThread(
|
||||||
await withVoidCallback((cb) {
|
app.engine, data.address, data.length, intensity, cb, nullptr);
|
||||||
Viewer_loadIblRenderThread(_viewer!, pathPtr, intensity, cb);
|
|
||||||
});
|
});
|
||||||
|
Scene_setIndirectLight(scene.scene, indirectLight!);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -345,12 +350,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future rotateIbl(Matrix3 rotationMatrix) async {
|
Future rotateIbl(Matrix3 rotationMatrix) async {
|
||||||
var floatPtr = allocator<Float>(9);
|
if (indirectLight == null) {
|
||||||
for (int i = 0; i < 9; i++) {
|
throw Exception("No IBL loaded");
|
||||||
floatPtr[i] = rotationMatrix.storage[i];
|
|
||||||
}
|
}
|
||||||
rotate_ibl(_viewer!, floatPtr);
|
IndirectLight_setRotation(indirectLight!, rotationMatrix.storage.address);
|
||||||
allocator.free(floatPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -358,9 +361,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeSkybox() async {
|
Future removeSkybox() async {
|
||||||
await withVoidCallback((cb) {
|
if (skybox != null) {
|
||||||
Viewer_removeSkyboxRenderThread(_viewer!, cb);
|
await withVoidCallback(
|
||||||
});
|
(cb) => Engine_destroySkyboxRenderThread(app.engine, skybox!, cb));
|
||||||
|
skybox = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -368,9 +373,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeIbl() async {
|
Future removeIbl() async {
|
||||||
await withVoidCallback((cb) {
|
if (indirectLight != null) {
|
||||||
Viewer_removeIblRenderThread(_viewer!, cb);
|
await withVoidCallback((cb) => Engine_destroyIndirectLightRenderThread(
|
||||||
});
|
app.engine, indirectLight!, cb));
|
||||||
|
indirectLight = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -408,35 +415,38 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
return addDirectLight(directLight);
|
return addDirectLight(directLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _lights = <ThermionEntity>{};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
||||||
var entity = await withIntCallback((cb) {
|
var entity = LightManager_createLight(
|
||||||
SceneManager_addLightRenderThread(
|
app.lightManager, TLightType.values[directLight.type.index]);
|
||||||
_sceneManager!,
|
|
||||||
directLight.type.index,
|
|
||||||
directLight.color,
|
|
||||||
directLight.intensity,
|
|
||||||
directLight.position.x,
|
|
||||||
directLight.position.y,
|
|
||||||
directLight.position.z,
|
|
||||||
directLight.direction.x,
|
|
||||||
directLight.direction.y,
|
|
||||||
directLight.direction.z,
|
|
||||||
directLight.falloffRadius,
|
|
||||||
directLight.spotLightConeInner,
|
|
||||||
directLight.spotLightConeOuter,
|
|
||||||
directLight.sunAngularRadius,
|
|
||||||
directLight.sunHaloSize,
|
|
||||||
directLight.sunHaloFallof,
|
|
||||||
directLight.castShadows,
|
|
||||||
cb);
|
|
||||||
});
|
|
||||||
if (entity == FILAMENT_ASSET_ERROR) {
|
if (entity == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("Failed to add light to scene");
|
throw Exception("Failed to add light to scene");
|
||||||
}
|
}
|
||||||
|
LightManager_setColor(app.lightManager, entity, directLight.color);
|
||||||
|
LightManager_setIntensity(app.lightManager, entity, directLight.intensity);
|
||||||
|
LightManager_setPosition(app.lightManager, entity, directLight.position.x,
|
||||||
|
directLight.position.y, directLight.position.z);
|
||||||
|
LightManager_setDirection(app.lightManager, entity, directLight.direction.x,
|
||||||
|
directLight.direction.y, directLight.direction.z);
|
||||||
|
LightManager_setFalloff(
|
||||||
|
app.lightManager, entity, directLight.falloffRadius);
|
||||||
|
LightManager_setSpotLightCone(app.lightManager, entity,
|
||||||
|
directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||||
|
// LightManager_setSunAngularRadius(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||||
|
// LightManager_setSunHaloSize(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||||
|
// LightManager_setSunHaloFalloff(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||||
|
LightManager_setShadowCaster(
|
||||||
|
app.lightManager, entity, directLight.castShadows);
|
||||||
|
|
||||||
|
Scene_addEntity(scene.scene, entity);
|
||||||
|
|
||||||
|
_lights.add(entity);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,9 +455,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeLight(ThermionEntity entity) async {
|
Future removeLight(ThermionEntity entity) async {
|
||||||
await withVoidCallback((cb) {
|
Scene_removeEntity(scene.scene, entity);
|
||||||
SceneManager_removeLightRenderThread(_sceneManager!, entity, cb);
|
LightManager_destroyLight(app.lightManager, entity);
|
||||||
});
|
_lights.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -455,34 +465,23 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future destroyLights() async {
|
Future destroyLights() async {
|
||||||
await withVoidCallback((cb) {
|
for (final light in _lights) {
|
||||||
SceneManager_destroyLightsRenderThread(_sceneManager!, cb);
|
await removeLight(light);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final _assets = <ThermionAsset>{};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionAsset> loadGlb(String path,
|
Future<ThermionAsset> loadGlb(String path,
|
||||||
{bool unlit = false, int numInstances = 1, bool keepData = false}) async {
|
{int numInstances = 1, bool keepData = false}) async {
|
||||||
if (unlit) {
|
final data = await assetLoader(path);
|
||||||
throw Exception("Not yet implemented");
|
|
||||||
}
|
|
||||||
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
|
||||||
var asset = await withPointerCallback<TSceneAsset>((callback) =>
|
|
||||||
SceneManager_loadGlbRenderThread(
|
|
||||||
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
|
||||||
|
|
||||||
allocator.free(pathPtr);
|
return loadGlbFromBuffer(data,
|
||||||
if (asset == nullptr) {
|
numInstances: numInstances, keepData: keepData);
|
||||||
throw Exception("An error occurred loading the asset at $path");
|
|
||||||
}
|
|
||||||
|
|
||||||
var thermionAsset = FFIAsset(
|
|
||||||
asset, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
|
|
||||||
|
|
||||||
return thermionAsset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -490,37 +489,29 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data,
|
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data,
|
||||||
{bool unlit = false,
|
{int numInstances = 1,
|
||||||
int numInstances = 1,
|
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
bool loadResourcesAsync = false}) async {
|
bool loadResourcesAsync = false}) async {
|
||||||
if (unlit) {
|
var asset = SceneAsset_loadGlb(
|
||||||
throw Exception("Not yet implemented");
|
app.gltfAssetLoader,
|
||||||
}
|
app.gltfResourceLoader,
|
||||||
|
app.engine,
|
||||||
if (layer < 0 || layer > 6) {
|
app.nameComponentManager,
|
||||||
throw Exception("Layer must be between 0 and 6");
|
|
||||||
}
|
|
||||||
|
|
||||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) =>
|
|
||||||
SceneManager_loadGlbFromBufferRenderThread(
|
|
||||||
_sceneManager!,
|
|
||||||
data.address,
|
data.address,
|
||||||
data.length,
|
data.length,
|
||||||
numInstances,
|
numInstances);
|
||||||
keepData,
|
|
||||||
priority,
|
|
||||||
layer,
|
|
||||||
loadResourcesAsync,
|
|
||||||
callback));
|
|
||||||
|
|
||||||
if (assetPtr == nullptr) {
|
if (asset == nullptr) {
|
||||||
throw Exception("An error occurred loading GLB from buffer");
|
throw Exception("An error occurred loading the asset");
|
||||||
}
|
}
|
||||||
return FFIAsset(
|
|
||||||
assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
|
var thermionAsset = FFIAsset(asset, app);
|
||||||
|
|
||||||
|
_assets.add(thermionAsset);
|
||||||
|
|
||||||
|
return thermionAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -1694,8 +1685,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<v64.Aabb3> getRenderableBoundingBox(ThermionEntity entityId) async {
|
Future<v64.Aabb3> getRenderableBoundingBox(ThermionEntity entityId) async {
|
||||||
final result =
|
final result = RenderableManager_getAabb(app.renderableManager, entityId);
|
||||||
SceneManager_getRenderableBoundingBox(_sceneManager!, entityId);
|
|
||||||
return v64.Aabb3.centerAndHalfExtents(
|
return v64.Aabb3.centerAndHalfExtents(
|
||||||
Vector3(result.centerX, result.centerY, result.centerZ),
|
Vector3(result.centerX, result.centerY, result.centerZ),
|
||||||
Vector3(result.halfExtentX, result.halfExtentY, result.halfExtentZ));
|
Vector3(result.halfExtentX, result.halfExtentY, result.halfExtentZ));
|
||||||
@@ -1706,10 +1696,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<v64.Aabb2> getViewportBoundingBox(ThermionEntity entityId) async {
|
Future<v64.Aabb2> getViewportBoundingBox(ThermionEntity entityId) async {
|
||||||
final view = (await getViewAt(0)) as FFIView;
|
throw UnimplementedError();
|
||||||
final result = get_bounding_box(_sceneManager!, view.view, entityId);
|
// final view = (await getViewAt(0)) as FFIView;
|
||||||
return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY),
|
// final result = get_bounding_box(_sceneManager!, view.view, entityId);
|
||||||
v64.Vector2(result.maxX, result.maxY));
|
// return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY),
|
||||||
|
// v64.Vector2(result.maxX, result.maxY));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export 'gltf.dart';
|
|||||||
|
|
||||||
export 'light_options.dart';
|
export 'light_options.dart';
|
||||||
|
|
||||||
// repre handle that can be safely passed back to the rendering layer to manipulate an Entity
|
// handle manipulate an Entity
|
||||||
typedef ThermionEntity = int;
|
typedef ThermionEntity = int;
|
||||||
|
|
||||||
abstract class ThermionAsset {
|
abstract class ThermionAsset {
|
||||||
@@ -66,15 +66,8 @@ abstract class ThermionAsset {
|
|||||||
///
|
///
|
||||||
Future<List<ThermionAsset>> getInstances();
|
Future<List<ThermionAsset>> getInstances();
|
||||||
|
|
||||||
///
|
Future setCastShadows(bool castShadows);
|
||||||
/// Adds all entities (renderable, lights and cameras) under [asset] to the scene.
|
Future setReceiveShadows(bool castShadows);
|
||||||
///
|
|
||||||
Future addToScene();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes all entities (renderable, lights and cameras) under [asset] from the scene.
|
|
||||||
///
|
|
||||||
Future removeFromScene();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Axis {
|
enum Axis {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ enum TransparencyMode {
|
|||||||
abstract class Material {
|
abstract class Material {
|
||||||
Future<MaterialInstance> createInstance();
|
Future<MaterialInstance> createInstance();
|
||||||
Future<bool> hasParameter(String propertyName);
|
Future<bool> hasParameter(String propertyName);
|
||||||
Future dispose();
|
Future destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MaterialInstance {
|
abstract class MaterialInstance {
|
||||||
@@ -146,5 +146,5 @@ abstract class MaterialInstance {
|
|||||||
|
|
||||||
Future setTransparencyMode(TransparencyMode mode);
|
Future setTransparencyMode(TransparencyMode mode);
|
||||||
|
|
||||||
Future dispose();
|
Future destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import 'package:thermion_dart/src/viewer/src/thermion_viewer_base.dart';
|
||||||
|
|
||||||
abstract class Scene {
|
abstract class Scene {
|
||||||
|
Future add(covariant ThermionAsset asset);
|
||||||
|
Future remove(covariant ThermionAsset asset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ abstract class ThermionViewer {
|
|||||||
/// Render a single frame and return the captured image as a pixel buffer.
|
/// Render a single frame and return the captured image as a pixel buffer.
|
||||||
///
|
///
|
||||||
Future<List<Uint8List>> capture(
|
Future<List<Uint8List>> capture(
|
||||||
covariant List<({View view, SwapChain? swapChain, RenderTarget? renderTarget})> targets);
|
covariant List<
|
||||||
|
({View view, SwapChain? swapChain, RenderTarget? renderTarget})>
|
||||||
|
targets);
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -108,12 +109,6 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
Future loadIbl(String lightingPath, {double intensity = 30000});
|
Future loadIbl(String lightingPath, {double intensity = 30000});
|
||||||
|
|
||||||
///
|
|
||||||
/// Creates a indirect light with the given color.
|
|
||||||
/// Only one indirect light can be active at any given time; if an indirect light has already been loaded, it will be replaced.
|
|
||||||
///
|
|
||||||
Future createIbl(double r, double g, double b, double intensity);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Rotates the IBL & skybox.
|
/// Rotates the IBL & skybox.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
|
||||||
#include <filament/Renderer.h>
|
|
||||||
#include <filament/View.h>
|
|
||||||
|
|
||||||
#include <math/vec3.h>
|
|
||||||
#include <math/vec4.h>
|
|
||||||
#include <math/mat3.h>
|
|
||||||
#include <math/norm.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "scene/SceneManager.hpp"
|
#include <filament/Renderer.h>
|
||||||
|
#include <filament/SwapChain.h>
|
||||||
|
#include <filament/View.h>
|
||||||
|
#include <filament/Viewport.h>
|
||||||
|
|
||||||
|
#include <filament/Camera.h>
|
||||||
|
#include <filament/Engine.h>
|
||||||
|
#include <filament/IndexBuffer.h>
|
||||||
|
#include <filament/Material.h>
|
||||||
|
#include <filament/MaterialInstance.h>
|
||||||
|
#include <filament/RenderableManager.h>
|
||||||
|
#include <filament/Scene.h>
|
||||||
|
#include <filament/TransformManager.h>
|
||||||
|
#include <filament/VertexBuffer.h>
|
||||||
|
|
||||||
|
#include "scene/AnimationManager.hpp"
|
||||||
|
|
||||||
namespace thermion
|
namespace thermion
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
typedef std::chrono::time_point time_point_t;
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
@@ -27,20 +33,24 @@ namespace thermion
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderTicker(filament::Renderer renderer, thermion::SceneManager sceneManager) : mRenderer(renderer), mSceneManager(sceneManager) { }
|
RenderTicker(filament::Renderer *renderer) : mRenderer(renderer) { }
|
||||||
~RenderTicker();
|
~RenderTicker();
|
||||||
|
|
||||||
void render(
|
void render(
|
||||||
uint64_t frameTimeInNanos
|
uint64_t frameTimeInNanos
|
||||||
);
|
);
|
||||||
void setRenderable(SwapChain *swapChain, View **view, uint8_t numViews);
|
void setRenderable(filament::SwapChain *swapChain, filament::View **view, uint8_t numViews);
|
||||||
|
|
||||||
|
void addAnimationManager(AnimationManager* animationManager);
|
||||||
|
void removeAnimationManager(AnimationManager* animationManager);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
Renderer *mRenderer = nullptr;
|
filament::Renderer *mRenderer = nullptr;
|
||||||
SceneManager *mSceneManager = nullptr;
|
std::vector<AnimationManager*> mAnimationManagers;
|
||||||
std::vector<SwapChain*> mSwapChains;
|
std::vector<filament::SwapChain*> mSwapChains;
|
||||||
std::map<SwapChain*, std::vector<View*>> mRenderable;
|
std::map<filament::SwapChain*, std::vector<filament::View*>> mRenderable;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TAnimationManager *AnimationManager_create(TEngine *tEngine);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_addAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_addAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_removeAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_removeAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine);
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Engine_buildMaterial(TEngine *tEngine, const uint8_t* materialData, size_t length);
|
EMSCRIPTEN_KEEPALIVE TMaterial *Engine_buildMaterial(TEngine *tEngine, const uint8_t* materialData, size_t length);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial);
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstance(TEngine *tEngine, TMaterialInstance *tMaterialInstance);
|
||||||
EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine);
|
EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine);
|
||||||
EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, uint8_t* ktxData, size_t length, void(*onTextureUploadComplete)());
|
EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, uint8_t* ktxData, size_t length, void(*onTextureUploadComplete)());
|
||||||
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, uint8_t* ktxData, size_t length, float intensity, void(*onTextureUploadComplete)());
|
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, uint8_t* ktxData, size_t length, float intensity, void(*onTextureUploadComplete)());
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void IndirectLight_setRotation(TIndirectLight TIndirectLight, double3x3 rotation);
|
EMSCRIPTEN_KEEPALIVE void IndirectLight_setRotation(TIndirectLight *tIndirectLight, double *rotation);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,19 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum TLightType {
|
||||||
|
LIGHT_TYPE_SUN,
|
||||||
|
LIGHT_TYPE_DIRECTIONAL,
|
||||||
|
LIGHT_TYPE_POINT,
|
||||||
|
LIGHT_TYPE_FOCUSED_SPOT,
|
||||||
|
LIGHT_TYPE_SPOT
|
||||||
|
};
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
||||||
EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager, EntityId entity, int type);
|
EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager, TLightType tLightTtype);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity);
|
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, double r, double g, double b);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, float colorTemperature);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setIntensity(TLightManager *tLightManager, EntityId entity, double intensity);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setIntensity(TLightManager *tLightManager, EntityId entity, double intensity);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setFalloff(TLightManager *tLightManager, EntityId entity, double falloff);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setFalloff(TLightManager *tLightManager, EntityId entity, double falloff);
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setSpotLightCone(TLightManager *tLightManager, EntityId entity, double inner, double outer);
|
EMSCRIPTEN_KEEPALIVE void LightManager_setSpotLightCone(TLightManager *tLightManager, EntityId entity, double inner, double outer);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
EMSCRIPTEN_KEEPALIVE TNameComponentManager *NameComponentManager_create();
|
||||||
EMSCRIPTEN_KEEPALIVE const char *NameComponentManager_getName(TNameComponentManager *tNameComponentManager, EntityId entity);
|
EMSCRIPTEN_KEEPALIVE const char *NameComponentManager_getName(TNameComponentManager *tNameComponentManager, EntityId entity);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer, TSceneManager *tSceneManager);
|
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_render(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos);
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_render(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_setRenderable(TRenderTicker *tFilamentRender, TSwapChain *swapChain, TView **views, uint8_t numViews);
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_setRenderable(TRenderTicker *tFilamentRender, TSwapChain *swapChain, TView **views, uint8_t numViews);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE void RenderableManager_setReceiveShadows(TRenderableManager *tRenderableManager, EntityId entityId, bool receiveShadows);
|
EMSCRIPTEN_KEEPALIVE void RenderableManager_setReceiveShadows(TRenderableManager *tRenderableManager, EntityId entityId, bool receiveShadows);
|
||||||
EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowReceiver(TRenderableManager *tRenderableManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowReceiver(TRenderableManager *tRenderableManager, EntityId entityId);
|
||||||
EMSCRIPTEN_KEEPALIVE bool RenderableManager_getFogEnabled(TRenderableManager *tRenderableManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE bool RenderableManager_getFogEnabled(TRenderableManager *tRenderableManager, EntityId entityId);
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 RenderableManager_getAabb(TRenderableManager *tRenderableManager, EntityId entityId);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ extern "C"
|
|||||||
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_addEntity(TScene* tScene, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE void Scene_addEntity(TScene* tScene, EntityId entityId);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Scene_removeEntity(TScene* tScene, EntityId entityId);
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *skybox);
|
EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *skybox);
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_setIndirectLight(TScene* tScene, TIndirectLight *tIndirectLight);
|
EMSCRIPTEN_KEEPALIVE void Scene_setIndirectLight(TScene* tScene, TIndirectLight *tIndirectLight);
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAsset(TScene* tScene, TFilamentAsset *asset);
|
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAsset(TScene* tScene, TFilamentAsset *asset);
|
||||||
|
|||||||
@@ -24,7 +24,29 @@ extern "C"
|
|||||||
TMaterialInstance **materialInstances,
|
TMaterialInstance **materialInstances,
|
||||||
int materialInstanceCount
|
int materialInstanceCount
|
||||||
);
|
);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb(
|
||||||
|
TGltfAssetLoader *tAssetLoader,
|
||||||
|
TGltfResourceLoader *tResourceLoader,
|
||||||
|
TEngine *tEngine,
|
||||||
|
TNameComponentManager *tNameComponentManager,
|
||||||
|
uint8_t *data,
|
||||||
|
size_t length,
|
||||||
|
size_t numInstances
|
||||||
|
);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGltf(
|
||||||
|
TGltfAssetLoader *tAssetLoader,
|
||||||
|
TGltfResourceLoader *tResourceLoader,
|
||||||
|
TEngine *tEngine,
|
||||||
|
TNameComponentManager *tNameComponentManager,
|
||||||
|
uint8_t *data,
|
||||||
|
size_t length,
|
||||||
|
size_t numInstances
|
||||||
|
);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene);
|
EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void SceneAsset_removeFromScene(TSceneAsset *tSceneAsset, TScene *tScene);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId SceneAsset_getEntity(TSceneAsset *tSceneAsset);
|
EMSCRIPTEN_KEEPALIVE EntityId SceneAsset_getEntity(TSceneAsset *tSceneAsset);
|
||||||
EMSCRIPTEN_KEEPALIVE int SceneAsset_getChildEntityCount(TSceneAsset* tSceneAsset);
|
EMSCRIPTEN_KEEPALIVE int SceneAsset_getChildEntityCount(TSceneAsset* tSceneAsset);
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_getChildEntities(TSceneAsset* tSceneAsset, EntityId *out);
|
EMSCRIPTEN_KEEPALIVE void SceneAsset_getChildEntities(TSceneAsset* tSceneAsset, EntityId *out);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ namespace thermion
|
|||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos,);
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos,);
|
||||||
// EMSCRIPTEN_KEEPALIVE void RenderLoop_addTask(TRenderLoop* tRenderLoop, void (*task)());
|
// EMSCRIPTEN_KEEPALIVE void RenderLoop_addTask(TRenderLoop* tRenderLoop, void (*task)());
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createRenderThread(
|
EMSCRIPTEN_KEEPALIVE void Engine_createRenderThread(
|
||||||
TBackend backend,
|
TBackend backend,
|
||||||
void* platform,
|
void* platform,
|
||||||
@@ -36,6 +38,7 @@ namespace thermion
|
|||||||
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
|
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)());
|
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)());
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, void (*onComplete)());
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)());
|
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)());
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)());
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)());
|
||||||
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
|
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ GIZMO_PACKAGE:
|
|||||||
GIZMO_GIZMO_OFFSET:
|
GIZMO_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
GIZMO_GIZMO_SIZE:
|
GIZMO_GIZMO_SIZE:
|
||||||
.int 45584
|
.int 45867
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _GIZMO_PACKAGE:
|
|||||||
_GIZMO_GIZMO_OFFSET:
|
_GIZMO_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_GIZMO_GIZMO_SIZE:
|
_GIZMO_GIZMO_SIZE:
|
||||||
.int 45584
|
.int 45867
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -8,5 +8,5 @@ GRID_PACKAGE:
|
|||||||
GRID_GRID_OFFSET:
|
GRID_GRID_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
GRID_GRID_SIZE:
|
GRID_GRID_SIZE:
|
||||||
.int 52130
|
.int 52018
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _GRID_PACKAGE:
|
|||||||
_GRID_GRID_OFFSET:
|
_GRID_GRID_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_GRID_GRID_SIZE:
|
_GRID_GRID_SIZE:
|
||||||
.int 52130
|
.int 52018
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -8,5 +8,5 @@ IMAGE_PACKAGE:
|
|||||||
IMAGE_IMAGE_OFFSET:
|
IMAGE_IMAGE_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
IMAGE_IMAGE_SIZE:
|
IMAGE_IMAGE_SIZE:
|
||||||
.int 56612
|
.int 63850
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _IMAGE_PACKAGE:
|
|||||||
_IMAGE_IMAGE_OFFSET:
|
_IMAGE_IMAGE_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_IMAGE_IMAGE_SIZE:
|
_IMAGE_IMAGE_SIZE:
|
||||||
.int 56612
|
.int 63850
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -8,5 +8,5 @@ UNLIT_PACKAGE:
|
|||||||
UNLIT_UNLIT_OFFSET:
|
UNLIT_UNLIT_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
UNLIT_UNLIT_SIZE:
|
UNLIT_UNLIT_SIZE:
|
||||||
.int 106370
|
.int 157994
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _UNLIT_PACKAGE:
|
|||||||
_UNLIT_UNLIT_OFFSET:
|
_UNLIT_UNLIT_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_UNLIT_UNLIT_SIZE:
|
_UNLIT_UNLIT_SIZE:
|
||||||
.int 106370
|
.int 157994
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -8,5 +8,5 @@ UNLIT_FIXED_SIZE_PACKAGE:
|
|||||||
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
||||||
.int 45632
|
.int 45907
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _UNLIT_FIXED_SIZE_PACKAGE:
|
|||||||
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
||||||
.int 45632
|
.int 45907
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
#include "TargetConditionals.h"
|
#include "TargetConditionals.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -6,35 +8,31 @@
|
|||||||
#pragma comment(lib, "Ws2_32.lib")
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <filament/Camera.h>
|
#include <math/mat4.h>
|
||||||
#include <filament/SwapChain.h>
|
#include <utils/EntityManager.h>
|
||||||
#include <backend/DriverEnums.h>
|
#include <utils/Panic.h>
|
||||||
#include <backend/platforms/OpenGLPlatform.h>
|
#include <utils/Systrace.h>
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <backend/platforms/PlatformWebGL.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/emscripten.h>
|
|
||||||
#include <emscripten/bind.h>
|
|
||||||
#include <emscripten/html5.h>
|
#include <emscripten/html5.h>
|
||||||
#include <emscripten/threading.h>
|
#include <emscripten/threading.h>
|
||||||
#include <emscripten/val.h>
|
#include <filament/webgl/WebEngine.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <filament/Box.h>
|
||||||
|
#include <filament/Camera.h>
|
||||||
|
#include <filament/ColorGrading.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/Options.h>
|
#include <filament/IndirectLight.h>
|
||||||
#include <filament/Renderer.h>
|
#include <filament/LightManager.h>
|
||||||
#include <filament/View.h>
|
#include <filament/Material.h>
|
||||||
|
#include <filament/MaterialInstance.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
|
#include <filament/Scene.h>
|
||||||
#include <iostream>
|
#include <filament/Skybox.h>
|
||||||
#include <streambuf>
|
#include <filament/TransformManager.h>
|
||||||
#include <sstream>
|
#include <filament/VertexBuffer.h>
|
||||||
#include <istream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <mutex>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
@@ -70,13 +68,32 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
|
|
||||||
mRenderable[swapChain] = swapChainViews;
|
mRenderable[swapChain] = swapChainViews;
|
||||||
|
|
||||||
|
// Keep track of the swapchains, so we can iterate them in the render method.
|
||||||
|
bool found = false;
|
||||||
|
for (auto existingSwapChain : mSwapChains) {
|
||||||
|
if (existingSwapChain == swapChain) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
mSwapChains.push_back(swapChain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderTicker::render(uint64_t frameTimeInNanos)
|
void RenderTicker::render(uint64_t frameTimeInNanos)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mMutex);
|
std::lock_guard lock(mMutex);
|
||||||
|
|
||||||
mSceneManager->update();
|
// Update all animation managers
|
||||||
|
for (auto animationManager : mAnimationManagers) {
|
||||||
|
if (animationManager) { // Check for nullptr just in case
|
||||||
|
animationManager->update(frameTimeInNanos * 1e-9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (auto swapChain : mSwapChains)
|
for (auto swapChain : mSwapChains)
|
||||||
{
|
{
|
||||||
@@ -99,5 +116,19 @@ namespace thermion
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderTicker::addAnimationManager(AnimationManager* animationManager) {
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
mAnimationManagers.push_back(animationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderTicker::removeAnimationManager(AnimationManager* animationManager) {
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
auto it = std::find(mAnimationManagers.begin(), mAnimationManagers.end(), animationManager);
|
||||||
|
if (it != mAnimationManagers.end()) {
|
||||||
|
mAnimationManagers.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderTicker::~RenderTicker() {}
|
||||||
|
|
||||||
} // namespace thermion
|
} // namespace thermion
|
||||||
@@ -10,6 +10,13 @@ extern "C"
|
|||||||
|
|
||||||
#include "c_api/TAnimationManager.h"
|
#include "c_api/TAnimationManager.h"
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TAnimationManager *AnimationManager_create(TEngine *tEngine, TScene *tScene) {
|
||||||
|
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||||
|
auto *scene = reinterpret_cast<filament::Scene *>(tScene);
|
||||||
|
auto animationManager = new AnimationManager(engine, scene);
|
||||||
|
return reinterpret_cast<TAnimationManager *>(animationManager);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_addAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId)
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_addAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId)
|
||||||
{
|
{
|
||||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||||
|
|||||||
@@ -162,6 +162,12 @@ namespace thermion
|
|||||||
engine->destroy(material);
|
engine->destroy(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstance(TEngine *tEngine, TMaterialInstance *tMaterialInstance) {
|
||||||
|
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||||
|
auto *mi = reinterpret_cast<MaterialInstance *>(tMaterialInstance);
|
||||||
|
engine->destroy(mi);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture)
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture)
|
||||||
{
|
{
|
||||||
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ namespace thermion
|
|||||||
using namespace filament;
|
using namespace filament;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void IndirectLight_setRotation(TIndirectLight *tIndirectLight, double3x3 rotation)
|
EMSCRIPTEN_KEEPALIVE void IndirectLight_setRotation(TIndirectLight *tIndirectLight, double *rotation)
|
||||||
{
|
{
|
||||||
auto *indirectLight = reinterpret_cast<filament::IndirectLight *>(tIndirectLight);
|
auto *indirectLight = reinterpret_cast<filament::IndirectLight *>(tIndirectLight);
|
||||||
const filament::math::mat3f fRotation {
|
const filament::math::mat3f fRotation {
|
||||||
filament::math::float3 { rotation.col1.x, rotation.col1.y, rotation.col1.z },
|
filament::math::float3 { static_cast<float>(rotation[0]), static_cast<float>(rotation[1]), static_cast<float>(rotation[2]) },
|
||||||
filament::math::float3 { rotation.col2.x, rotation.col2.y, rotation.col2.z },
|
filament::math::float3 { static_cast<float>(rotation[3]), static_cast<float>(rotation[4]), static_cast<float>(rotation[5]) },
|
||||||
filament::math::float3 { rotation.col3.x, rotation.col3.y, rotation.col3.z },
|
filament::math::float3 { static_cast<float>(rotation[6]), static_cast<float>(rotation[7]), static_cast<float>(rotation[8]) },
|
||||||
};
|
};
|
||||||
indirectLight->setRotation(fRotation);
|
indirectLight->setRotation(fRotation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
|
||||||
#include <filament/LightManager.h>
|
#include <filament/LightManager.h>
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
|
#include <utils/EntityManager.h>
|
||||||
|
|
||||||
#include "c_api/APIExport.h"
|
#include "c_api/APIExport.h"
|
||||||
#include "Log.hpp"
|
|
||||||
#include "c_api/TLightManager.h"
|
#include "c_api/TLightManager.h"
|
||||||
|
|
||||||
|
#include "Log.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z) {
|
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z) {
|
||||||
@@ -27,8 +31,9 @@ EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager
|
|||||||
lightManager->setDirection(instance, filament::math::float3 { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) });
|
lightManager->setDirection(instance, filament::math::float3 { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) });
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager, EntityId entity, int type) {
|
EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TEngine *tEngine, TLightManager *tLightManager, TLightType type) {
|
||||||
auto* lm = reinterpret_cast<filament::LightManager*>(tLightManager);
|
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||||
|
auto *lightManager = reinterpret_cast<filament::LightManager*>(tLightManager);
|
||||||
filament::LightManager::Type lightType;
|
filament::LightManager::Type lightType;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -41,9 +46,12 @@ EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
filament::LightManager::Builder builder(lightType);
|
filament::LightManager::Builder builder(lightType);
|
||||||
return false;
|
auto entity = utils::EntityManager::create();
|
||||||
// auto result = builder.build(*lm->getEngine(), utils::Entity::import(entity));
|
auto result = builder.build(*engine, utils::Entity::import(entity));
|
||||||
// return result == filament::LightManager::Result::Success ? 0 : -1;
|
if(result != filament::LightManager::Result::Success) {
|
||||||
|
Log("Failed to create light");
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) {
|
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) {
|
||||||
@@ -51,11 +59,13 @@ EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager
|
|||||||
lm->destroy(utils::Entity::import(entity));
|
lm->destroy(utils::Entity::import(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, double r, double g, double b) {
|
EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, float colorTemperature) {
|
||||||
auto* lm = reinterpret_cast<filament::LightManager*>(tLightManager);
|
auto* lm = reinterpret_cast<filament::LightManager*>(tLightManager);
|
||||||
|
auto color = filament::Color::cct(colorTemperature);
|
||||||
|
|
||||||
auto instance = lm->getInstance(utils::Entity::import(entity));
|
auto instance = lm->getInstance(utils::Entity::import(entity));
|
||||||
if (instance.isValid()) {
|
if (instance.isValid()) {
|
||||||
lm->setColor(instance, {static_cast<float>(r), static_cast<float>(g), static_cast<float>(b)});
|
lm->setColor(instance, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TNameComponentManager *NameComponentManager_create()
|
||||||
|
{
|
||||||
|
auto *ncm = new utils::NameComponentManager(utils::EntityManager::get());
|
||||||
|
return reinterpret_cast<TNameComponentManager *>(ncm);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE const char *NameComponentManager_getName(TNameComponentManager *tNameComponentManager, EntityId entity)
|
EMSCRIPTEN_KEEPALIVE const char *NameComponentManager_getName(TNameComponentManager *tNameComponentManager, EntityId entity)
|
||||||
{
|
{
|
||||||
auto ncm = reinterpret_cast<utils::NameComponentManager *>(tNameComponentManager);
|
auto ncm = reinterpret_cast<utils::NameComponentManager *>(tNameComponentManager);
|
||||||
|
|||||||
@@ -18,13 +18,24 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#include "c_api/TRenderTicker.hpp"
|
#include "c_api/TRenderTicker.hpp"
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer, TSceneManager *tSceneManager) {
|
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer) {
|
||||||
auto *renderer = reinterpret_cast<filament::Renderer *>(tRenderer);
|
auto *renderer = reinterpret_cast<filament::Renderer *>(tRenderer);
|
||||||
auto *sceneManager = reinterpret_cast<thermion::SceneManager *>(tSceneManager);
|
auto *renderTicker = new RenderTicker(renderer);
|
||||||
auto *renderTicker = new RenderTicker(renderer, sceneManager);
|
|
||||||
return reinterpret_cast<TRenderTicker *>(renderTicker);
|
return reinterpret_cast<TRenderTicker *>(renderTicker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager) {
|
||||||
|
auto *renderTicker = reinterpret_cast<RenderTicker *>(tRenderTicker);
|
||||||
|
auto *animationManager = reinterpret_cast<thermion::AnimationManager *>(tAnimationManager);
|
||||||
|
renderTicker->addAnimationManager(animationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager) {
|
||||||
|
auto *renderTicker = reinterpret_cast<RenderTicker *>(tRenderTicker);
|
||||||
|
auto *animationManager = reinterpret_cast<thermion::AnimationManager *>(tAnimationManager);
|
||||||
|
renderTicker->removeAnimationManager(animationManager);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_render(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos) {
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_render(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos) {
|
||||||
auto *renderTicker = reinterpret_cast<RenderTicker *>
|
auto *renderTicker = reinterpret_cast<RenderTicker *>
|
||||||
renderTicker->render(frameTimeInNanos);
|
renderTicker->render(frameTimeInNanos);
|
||||||
|
|||||||
@@ -120,5 +120,16 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
return renderableManager->getFogEnabled(renderableInstance);
|
return renderableManager->getFogEnabled(renderableInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 RenderableManager_getAabb(TRenderableManager *tRenderableManager, EntityId entityId) {
|
||||||
|
auto *renderableManager = reinterpret_cast<filament::RenderableManager *>(tRenderableManager);
|
||||||
|
const auto &entity = utils::Entity::import(entityId);
|
||||||
|
auto renderableInstance = renderableManager->getInstance(entity);
|
||||||
|
if (!renderableInstance.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto box = rm.getAxisAlignedBoundingBox(instance);
|
||||||
|
return Aabb3{box.center.x, box.center.y, box.center.z, box.halfExtent.x, box.halfExtent.y, box.halfExtent.z};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,11 @@ namespace thermion
|
|||||||
scene->addEntity(utils::Entity::import(entityId));
|
scene->addEntity(utils::Entity::import(entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Scene_removeEntity(TScene* tScene, EntityId entityId) {
|
||||||
|
auto *scene = reinterpret_cast<Scene *>(tScene);
|
||||||
|
scene->removeEntity(utils::Entity::import(entityId));
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *tSkybox) {
|
EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *tSkybox) {
|
||||||
auto *scene = reinterpret_cast<Scene *>(tScene);
|
auto *scene = reinterpret_cast<Scene *>(tScene);
|
||||||
auto *skybox = reinterpret_cast<Skybox *>(tSkybox);
|
auto *skybox = reinterpret_cast<Skybox *>(tSkybox);
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
|
|
||||||
|
#include <gltfio/AssetLoader.h>
|
||||||
|
#include <gltfio/ResourceLoader.h>
|
||||||
|
|
||||||
|
#include <utils/NameComponentManager.h>
|
||||||
|
|
||||||
|
#include "c_api/TGltfAssetLoader.h"
|
||||||
#include "c_api/TSceneAsset.h"
|
#include "c_api/TSceneAsset.h"
|
||||||
#include "scene/SceneAsset.hpp"
|
#include "scene/SceneAsset.hpp"
|
||||||
#include "scene/GltfSceneAsset.hpp"
|
#include "scene/GltfSceneAsset.hpp"
|
||||||
@@ -59,12 +65,43 @@ extern "C"
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb(
|
||||||
|
TGltfAssetLoader *tAssetLoader,
|
||||||
|
TGltfResourceLoader *tResourceLoader,
|
||||||
|
TEngine *tEngine,
|
||||||
|
TNameComponentManager *tNameComponentManager,
|
||||||
|
uint8_t *data,
|
||||||
|
size_t length,
|
||||||
|
size_t numInstances
|
||||||
|
) {
|
||||||
|
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||||
|
auto *nameComponentManager = reinterpret_cast<utils::NameComponentManager *>(tNameComponentManager);
|
||||||
|
auto *tFilamentAsset = GltfAssetLoader_load(tAssetLoader, tResourceLoader, data, length, numInstances);
|
||||||
|
auto *filamentAsset = reinterpret_cast<filament::gltfio::FilamentAsset *>(tFilamentAsset);
|
||||||
|
auto *assetLoader = reinterpret_cast<filament::gltfio::AssetLoader *>(tAssetLoader);
|
||||||
|
auto *resourceLoader = reinterpret_cast<filament::gltfio::ResourceLoader *>(tResourceLoader);
|
||||||
|
auto *sceneAsset = new GltfSceneAsset(
|
||||||
|
filamentAsset,
|
||||||
|
assetLoader,
|
||||||
|
engine,
|
||||||
|
nameComponentManager
|
||||||
|
);
|
||||||
|
return reinterpret_cast<TSceneAsset *>(sceneAsset);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene) {
|
EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene) {
|
||||||
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
||||||
auto *scene = reinterpret_cast<Scene*>(tScene);
|
auto *scene = reinterpret_cast<Scene*>(tScene);
|
||||||
asset->addAllEntities(scene);
|
asset->addAllEntities(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void SceneAsset_removeFromScene(TSceneAsset *tSceneAsset, TScene *tScene) {
|
||||||
|
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
||||||
|
auto *scene = reinterpret_cast<Scene*>(tScene);
|
||||||
|
asset->removeAllEntities(scene);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId SceneAsset_getEntity(TSceneAsset *tSceneAsset) {
|
EMSCRIPTEN_KEEPALIVE EntityId SceneAsset_getEntity(TSceneAsset *tSceneAsset) {
|
||||||
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
||||||
return utils::Entity::smuggle(asset->getEntity());
|
return utils::Entity::smuggle(asset->getEntity());
|
||||||
|
|||||||
@@ -683,6 +683,16 @@ extern "C"
|
|||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *)) {
|
||||||
|
std::packaged_task<void()> lambda(
|
||||||
|
[=]() mutable
|
||||||
|
{
|
||||||
|
auto *animationManager = AnimationManager_create(tEngine, tScene);
|
||||||
|
callback(animationManager);
|
||||||
|
});
|
||||||
|
auto fut = _rl->add_task(lambda);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
|
||||||
TAnimationManager *tAnimationManager,
|
TAnimationManager *tAnimationManager,
|
||||||
TSceneAsset *sceneAsset,
|
TSceneAsset *sceneAsset,
|
||||||
|
|||||||
Reference in New Issue
Block a user