add texture methods (including unproject)
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user