add texture methods (including unproject)

This commit is contained in:
Nick Fisher
2024-09-16 20:51:14 +08:00
parent 773077ab9c
commit 60dbc4ffd6
19 changed files with 1093 additions and 724 deletions

View File

@@ -1,14 +1,16 @@
import 'dart:math';
import 'dart:typed_data';
import 'package:thermion_dart/thermion_dart/viewer/shared_types/geometry.dart';
import 'package:thermion_dart/thermion_dart/viewer/thermion_viewer_base.dart';
class GeometryHelper {
static Geometry sphere({bool normals = true, bool uvs = true}) {
int latitudeBands = 20;
int longitudeBands = 20;
List<double> vertices = [];
List<double> _normals = [];
List<double> verticesList = [];
List<double> normalsList = [];
List<double> uvsList = [];
List<int> indices = [];
for (int latNumber = 0; latNumber <= latitudeBands; latNumber++) {
@@ -25,12 +27,10 @@ class GeometryHelper {
double y = cosTheta;
double z = sinPhi * sinTheta;
vertices.addAll([x, y, z]);
_normals.addAll([
x,
y,
z
]); // For a sphere, normals are the same as vertex positions
verticesList.addAll([x, y, z]);
normalsList.addAll([x, y, z]);
uvsList.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
}
}
@@ -39,127 +39,171 @@ class GeometryHelper {
int first = (latNumber * (longitudeBands + 1)) + longNumber;
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]);
}
}
return Geometry(vertices, indices, normals: normals ? _normals : null);
Float32List vertices = Float32List.fromList(verticesList);
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
}
static Geometry cube({bool normals = true, bool uvs = true}) {
final vertices = <double>[
// Front face
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
static Geometry cube({bool normals = true, bool uvs = true}) {
final vertices = Float32List.fromList([
// Front face
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
// Back face
-1, -1, -1,
-1, 1, -1,
1, 1, -1,
1, -1, -1,
// Back face
-1, -1, -1,
-1, 1, -1,
1, 1, -1,
1, -1, -1,
// Top face
-1, 1, -1,
-1, 1, 1,
1, 1, 1,
1, 1, -1,
// Top face
-1, 1, -1,
-1, 1, 1,
1, 1, 1,
1, 1, -1,
// Bottom face
-1, -1, -1,
1, -1, -1,
1, -1, 1,
-1, -1, 1,
// Bottom face
-1, -1, -1,
1, -1, -1,
1, -1, 1,
-1, -1, 1,
// Right face
1, -1, -1,
1, 1, -1,
1, 1, 1,
1, -1, 1,
// Right face
1, -1, -1,
1, 1, -1,
1, 1, 1,
1, -1, 1,
// Left face
-1, -1, -1,
-1, -1, 1,
-1, 1, 1,
-1, 1, -1,
];
// Left face
-1, -1, -1,
-1, -1, 1,
-1, 1, 1,
-1, 1, -1,
]);
final _normals = <double>[
// Front face
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
final _normals = normals ? Float32List.fromList([
// Front face
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
// Back face
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
// Back face
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
// Top face
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
// Top face
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
// Bottom face
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
// Bottom face
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
// Right face
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// Right face
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// Left face
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
];
// Left face
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
]) : null;
final indices = [
// Front face
0, 1, 2, 0, 2, 3,
// Back face
4, 5, 6, 4, 6, 7,
// Top face
8, 9, 10, 8, 10, 11,
// Bottom face
12, 13, 14, 12, 14, 15,
// Right face
16, 17, 18, 16, 18, 19,
// Left face
20, 21, 22, 20, 22, 23
];
return Geometry(vertices, indices, normals: normals ? _normals : null);
}
final _uvs = uvs ? Float32List.fromList([
// Front face
1/3, 1/3,
2/3, 1/3,
2/3, 2/3,
1/3, 2/3,
// Back face
2/3, 2/3,
2/3, 1,
1, 1,
1, 2/3,
// Top face
1/3, 0,
1/3, 1/3,
2/3, 1/3,
2/3, 0,
// Bottom face
1/3, 2/3,
2/3, 2/3,
2/3, 1,
1/3, 1,
// Right face
2/3, 1/3,
2/3, 2/3,
1, 2/3,
1, 1/3,
// Left face
0, 1/3,
1/3, 1/3,
1/3, 2/3,
0, 2/3,
]) : null;
final indices = [
// Front face
0, 1, 2, 0, 2, 3,
// Back face
4, 5, 6, 4, 6, 7,
// Top face
8, 9, 10, 8, 10, 11,
// Bottom face
12, 13, 14, 12, 14, 15,
// Right face
16, 17, 18, 16, 18, 19,
// Left face
20, 21, 22, 20, 22, 23
];
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
}
static Geometry cylinder({double radius = 1.0, double length = 1.0, bool normals = true, bool uvs = true }) {
int segments = 32;
List<double> vertices = [];
List<double> _normals = [];
List<double> verticesList = [];
List<double> normalsList = [];
List<double> uvsList = [];
List<int> indices = [];
// Create vertices and normals
// Create vertices, normals, and UVs
for (int i = 0; i <= segments; i++) {
double theta = i * 2 * pi / segments;
double x = radius * cos(theta);
double z = radius * sin(theta);
// Top circle
vertices.addAll([x, length / 2, z]);
_normals.addAll([x / radius, 0, z / radius]);
verticesList.addAll([x, length / 2, z]);
normalsList.addAll([x / radius, 0, z / radius]);
uvsList.addAll([i / segments, 1]);
// Bottom circle
vertices.addAll([x, -length / 2, z]);
_normals.addAll([x / radius, 0, z / radius]);
verticesList.addAll([x, -length / 2, z]);
normalsList.addAll([x / radius, 0, z / radius]);
uvsList.addAll([i / segments, 0]);
}
// Create indices
@@ -178,45 +222,62 @@ class GeometryHelper {
indices.addAll([bottomFirst, bottomSecond, topSecond]);
}
// Add center vertices and normals for top and bottom faces
vertices.addAll([0, length / 2, 0]); // Top center
_normals.addAll([0, 1, 0]);
vertices.addAll([0, -length / 2, 0]); // Bottom center
_normals.addAll([0, -1, 0]);
// Add center vertices, normals, and UVs for top and bottom faces
verticesList.addAll([0, length / 2, 0]); // Top center
normalsList.addAll([0, 1, 0]);
uvsList.addAll([0.5, 0.5]); // Center of top face
// Add top and bottom face normals
verticesList.addAll([0, -length / 2, 0]); // Bottom center
normalsList.addAll([0, -1, 0]);
uvsList.addAll([0.5, 0.5]); // Center of bottom face
// Add top and bottom face normals and UVs
for (int i = 0; i <= segments; i++) {
_normals.addAll([0, 1, 0]); // Top face normal
_normals.addAll([0, -1, 0]); // Bottom face normal
normalsList.addAll([0, 1, 0]); // Top face normal
normalsList.addAll([0, -1, 0]); // Bottom face normal
double u = 0.5 + 0.5 * cos(i * 2 * pi / segments);
double v = 0.5 + 0.5 * sin(i * 2 * pi / segments);
uvsList.addAll([u, v]); // Top face UV
uvsList.addAll([u, v]); // Bottom face UV
}
return Geometry(vertices, indices, normals: normals ? _normals : null);
Float32List vertices = Float32List.fromList(verticesList);
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
}
static Geometry conic({double radius = 1.0, double length = 1.0, bool normals = true, bool uvs = true}) {
int segments = 32;
List<double> vertices = [];
List<double> _normals = [];
List<double> verticesList = [];
List<double> normalsList = [];
List<double> uvsList = [];
List<int> indices = [];
// Create vertices and normals
// Create vertices, normals, and UVs
for (int i = 0; i <= segments; i++) {
double theta = i * 2 * pi / segments;
double x = radius * cos(theta);
double z = radius * sin(theta);
// Base circle
vertices.addAll([x, 0, z]);
verticesList.addAll([x, 0, z]);
// Calculate normal for the side
double nx = x / sqrt(x * x + length * length);
double nz = z / sqrt(z * z + length * length);
double ny = radius / sqrt(radius * radius + length * length);
_normals.addAll([nx, ny, nz]);
normalsList.addAll([nx, ny, nz]);
// UV coordinates
uvsList.addAll([i / segments, 0]);
}
// Apex
vertices.addAll([0, length, 0]);
_normals.addAll([0, 1, 0]); // Normal at apex points straight up
verticesList.addAll([0, length, 0]);
normalsList.addAll([0, 1, 0]); // Normal at apex points straight up
uvsList.addAll([0.5, 1]); // UV for apex
// Create indices
for (int i = 0; i < segments; i++) {
@@ -226,54 +287,48 @@ class GeometryHelper {
indices.addAll([i, segments, i + 1]);
}
// Add base face normals
// Add base face normals and UVs
for (int i = 0; i <= segments; i++) {
_normals.addAll([0, -1, 0]); // Base face normal
normalsList.addAll([0, -1, 0]); // Base face normal
double u = 0.5 + 0.5 * cos(i * 2 * pi / segments);
double v = 0.5 + 0.5 * sin(i * 2 * pi / segments);
uvsList.addAll([u, v]); // Base face UV
}
return Geometry(vertices, indices, normals: normals ? _normals : null);
Float32List vertices = Float32List.fromList(verticesList);
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
}
static Geometry plane({double width = 1.0, double height = 1.0, bool normals = true, bool uvs = true}) {
List<double> vertices = [
-width / 2,
0,
-height / 2,
width / 2,
0,
-height / 2,
width / 2,
0,
height / 2,
-width / 2,
0,
height / 2,
];
Float32List vertices = Float32List.fromList([
-width / 2, 0, -height / 2,
width / 2, 0, -height / 2,
width / 2, 0, height / 2,
-width / 2, 0, height / 2,
]);
List<double> _normals = [
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
];
Float32List? _normals = normals ? Float32List.fromList([
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
]) : null;
Float32List? _uvs = uvs ? Float32List.fromList([
0, 0,
1, 0,
1, 1,
0, 1,
]) : null;
List<int> indices = [
0,
2,
1,
0,
3,
2,
0, 2, 1,
0, 3, 2,
];
return Geometry(vertices, indices, normals: normals ? _normals : null);
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
}
}
}

View File

@@ -1039,37 +1039,22 @@ external void remove_animation_component(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Uint16>,
ffi.Int,
ffi.Int,
ffi.Pointer<ffi.Char>)>(isLeaf: true)
external int create_geometry(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int primitiveType,
ffi.Pointer<ffi.Char> materialPath,
);
@ffi.Native<
EntityId Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Uint16>,
ffi.Int,
ffi.Int,
ffi.Pointer<ffi.Char>)>(isLeaf: true)
external int create_geometry_with_normals(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Float> normals,
int numNormals,
ffi.Pointer<ffi.Float> uvs,
int numUvs,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int primitiveType,
@@ -1214,6 +1199,44 @@ external void set_material_property_float4(
float4 value,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Uint8>,
ffi.Uint32, ffi.Uint32)>(isLeaf: true)
external void unproject_texture(
ffi.Pointer<ffi.Void> sceneManager,
int entity,
ffi.Pointer<ffi.Uint8> out,
int outWidth,
int outHeight,
);
@ffi.Native<
ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Uint8>, ffi.Size)>(isLeaf: true)
external ffi.Pointer<ffi.Void> create_texture(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Uint8> data,
int length,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>(
isLeaf: true)
external void destroy_texture(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Void> texture,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Char>, ffi.Int)>(isLeaf: true)
external void apply_texture_to_material(
ffi.Pointer<ffi.Void> sceneManager,
int entity,
ffi.Pointer<ffi.Void> texture,
ffi.Pointer<ffi.Char> parameterName,
int materialIndex,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.Void>,
@@ -1683,6 +1706,10 @@ external void reset_to_rest_pose_ffi(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Uint16>,
ffi.Int,
ffi.Int,
@@ -1694,6 +1721,10 @@ external void create_geometry_ffi(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Float> normals,
int numNormals,
ffi.Pointer<ffi.Float> uvs,
int numUvs,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int primitiveType,
@@ -1703,31 +1734,20 @@ external void create_geometry_ffi(
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Float>,
ffi.Int,
ffi.Pointer<ffi.Uint16>,
ffi.Int,
ffi.Int,
ffi.Pointer<ffi.Char>,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
isLeaf: true)
external void create_geometry_with_normals_ffi(
ffi.Void Function(
ffi.Pointer<ffi.Void>,
EntityId,
ffi.Pointer<ffi.Uint8>,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void unproject_texture_ffi(
ffi.Pointer<ffi.Void> sceneManager,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Float> normals,
int numNormals,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int primitiveType,
ffi.Pointer<ffi.Char> materialPath,
bool keepData,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
int entity,
ffi.Pointer<ffi.Uint8> out,
int outWidth,
int outHeight,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
);
final class ResourceBuffer extends ffi.Struct {

View File

@@ -58,7 +58,8 @@ class ThermionViewerFFI extends ThermionViewer {
///
Stream<SceneUpdateEvent> get sceneUpdated =>
_sceneUpdateEventController.stream;
final _sceneUpdateEventController = StreamController<SceneUpdateEvent>.broadcast();
final _sceneUpdateEventController =
StreamController<SceneUpdateEvent>.broadcast();
final Pointer<Void> resourceLoader;
@@ -355,9 +356,6 @@ class ThermionViewerFFI extends ThermionViewer {
remove_ibl_ffi(_viewer!);
}
///
///
///
@override
Future<ThermionEntity> addLight(
LightType type,
@@ -376,30 +374,21 @@ class ThermionViewerFFI extends ThermionViewer {
double sunHaloSize = 10.0,
double sunHaloFallof = 80.0,
bool castShadows = true}) async {
var entity = await withIntCallback((callback) => add_light_ffi(
_viewer!,
type.index,
colour,
intensity,
posX,
posY,
posZ,
dirX,
dirY,
dirZ,
falloffRadius,
spotLightConeInner,
spotLightConeOuter,
sunAngularRadius = 0.545,
sunHaloSize = 10.0,
sunHaloFallof = 80.0,
castShadows,
callback));
if (entity == _FILAMENT_ASSET_ERROR) {
throw Exception("Failed to add light to scene");
}
DirectLight directLight = DirectLight(
type: type,
color: colour,
intensity: intensity,
position: Vector3(posX, posY, posZ),
direction: Vector3(dirX, dirY, dirZ),
falloffRadius: falloffRadius,
spotLightConeInner: spotLightConeInner,
spotLightConeOuter: spotLightConeOuter,
sunAngularRadius: sunAngularRadius,
sunHaloSize: sunHaloSize,
sunHaloFallof: sunHaloFallof,
castShadows: castShadows);
return entity;
return addDirectLight(directLight);
}
///
@@ -1827,49 +1816,25 @@ class ThermionViewerFFI extends ThermionViewer {
final materialPathPtr =
geometry.materialPath?.toNativeUtf8(allocator: allocator) ?? nullptr;
final vertexPtr = allocator<Float>(geometry.vertices.length);
final indicesPtr = allocator<Uint16>(geometry.indices.length);
for (int i = 0; i < geometry.vertices.length; i++) {
vertexPtr[i] = geometry.vertices[i];
}
for (int i = 0; i < geometry.indices.length; i++) {
(indicesPtr + i).value = geometry.indices[i];
}
var normalsPtr = nullptr.cast<Float>();
if (geometry.normals != null) {
normalsPtr = allocator<Float>(geometry.normals!.length);
for (int i = 0; i < geometry.normals!.length; i++) {
normalsPtr[i] = geometry.normals![i];
}
}
var entity = await withIntCallback((callback) =>
create_geometry_with_normals_ffi(
_sceneManager!,
vertexPtr,
geometry.vertices.length,
normalsPtr,
geometry.normals?.length ?? 0,
indicesPtr,
geometry.indices.length,
geometry.primitiveType.index,
materialPathPtr.cast<Char>(),
keepData,
callback));
var entity = await withIntCallback((callback) => create_geometry_ffi(
_sceneManager!,
geometry.vertices.address,
geometry.vertices.length,
geometry.normals.address,
geometry.normals.length,
geometry.uvs.address,
geometry.uvs.length,
geometry.indices.address,
geometry.indices.length,
geometry.primitiveType.index,
materialPathPtr.cast<Char>(),
keepData,
callback));
if (entity == _FILAMENT_ASSET_ERROR) {
throw Exception("Failed to create geometry");
}
allocator.free(materialPathPtr);
allocator.free(vertexPtr);
allocator.free(indicesPtr);
if (geometry.normals != null) {
allocator.free(normalsPtr);
}
_sceneUpdateEventController
.add(SceneUpdateEvent.addGeometry(entity, geometry));
@@ -2001,4 +1966,38 @@ class ThermionViewerFFI extends ThermionViewer {
_sceneManager!, entity, materialIndex, ptr.cast<Char>(), struct);
allocator.free(ptr);
}
Future<Uint8List> unproject(
ThermionEntity entity, int outWidth, int outHeight) async {
final outPtr = Uint8List(outWidth * outHeight * 4);
await withVoidCallback((callback) {
unproject_texture_ffi(
_viewer!, entity, outPtr.address, outWidth, outHeight, callback);
});
return outPtr.buffer.asUint8List();
}
Future<ThermionTexture> createTexture(Uint8List data) async {
var ptr = create_texture(_sceneManager!, data.address, data.length);
return ThermionFFITexture(ptr);
}
Future applyTexture(ThermionFFITexture texture, ThermionEntity entity,
{int materialIndex = 0, String parameterName = "baseColorMap"}) async {
using(parameterName.toNativeUtf8(), (namePtr) async {
apply_texture_to_material(_sceneManager!, entity, texture._pointer,
namePtr.cast<Char>(), materialIndex);
});
}
Future destroyTexture(ThermionFFITexture texture) async {
destroy_texture(_sceneManager!, texture._pointer);
}
}
class ThermionFFITexture extends ThermionTexture {
final Pointer<Void> _pointer;
ThermionFFITexture(this._pointer);
}

View File

@@ -7,3 +7,7 @@ export 'light_options.dart';
// a handle that can be safely passed back to the rendering layer to manipulate an Entity
typedef ThermionEntity = int;
abstract class ThermionTexture {
}

View File

@@ -1,19 +1,34 @@
import 'dart:typed_data';
import 'package:thermion_dart/thermion_dart/viewer/thermion_viewer_base.dart';
class Geometry {
final List<double> vertices;
final List<int> indices;
final List<double>? normals;
final List<(double, double)>? uvs;
final Float32List vertices;
final Uint16List indices;
final Float32List normals;
final Float32List uvs;
final PrimitiveType primitiveType;
final String? materialPath;
Geometry(this.vertices, this.indices, { this.normals=null, this.uvs=null,
this.primitiveType = PrimitiveType.TRIANGLES, this.materialPath = null});
Geometry(
this.vertices,
List<int> indices, {
Float32List? normals,
Float32List? uvs,
this.primitiveType = PrimitiveType.TRIANGLES,
this.materialPath,
}) : indices = Uint16List.fromList(indices),
normals = normals ?? Float32List(0),
uvs = uvs ?? Float32List(0) {
assert(this.uvs.length == 0 || this.uvs.length == (vertices.length ~/ 3) * 2);
}
void scale(double factor) {
for (int i = 0; i < vertices.length; i++) {
vertices[i] = vertices[i] * factor;
}
}
bool get hasNormals => normals.isNotEmpty;
bool get hasUVs => uvs.isNotEmpty;
}

View File

@@ -11,10 +11,9 @@ import 'dart:async';
import 'package:animation_tools_dart/animation_tools_dart.dart';
abstract class ThermionViewer {
///
///
/// A Future that resolves when the underlying rendering context has been successfully created.
///
///
Future<bool> get initialized;
///
@@ -136,7 +135,8 @@ abstract class ThermionViewer {
/// Note that [sunAngularRadius] is in degrees,
/// whereas [spotLightConeInner] and [spotLightConeOuter] are in radians
///
@Deprecated("This will be removed in future versions. Use addDirectLight instead.")
@Deprecated(
"This will be removed in future versions. Use addDirectLight instead.")
Future<ThermionEntity> addLight(
LightType type,
double colour,
@@ -161,8 +161,7 @@ abstract class ThermionViewer {
/// Note that [sunAngularRadius] is in degrees,
/// whereas [spotLightConeInner] and [spotLightConeOuter] are in radians
///
Future<ThermionEntity> addDirectLight(
DirectLight light);
Future<ThermionEntity> addDirectLight(DirectLight light);
///
/// Remove a light from the scene.
@@ -787,7 +786,7 @@ abstract class ThermionViewer {
/// Creates a (renderable) entity with the specified geometry and adds to the scene.
/// If [keepData] is true, the source data will not be released.
///
Future createGeometry(Geometry geometry, { bool keepData= false});
Future createGeometry(Geometry geometry, {bool keepData = false});
///
/// Gets the parent entity of [entity]. Returns null if the entity has no parent.
@@ -853,4 +852,21 @@ abstract class ThermionViewer {
/// Removes the outline around [entity]. Noop if there was no highlight.
///
Future removeStencilHighlight(ThermionEntity entity);
///
/// Decodes the specified image data and creates a texture.
///
Future<ThermionTexture> createTexture(Uint8List data);
///
///
///
Future applyTexture(covariant ThermionTexture texture, ThermionEntity entity,
{int materialIndex = 0, String parameterName = "baseColorMap"});
///
///
///
Future destroyTexture(covariant ThermionTexture texture);
}