Open limefrogyank opened 3 years ago
I can see having a binary transfer abstraction might work here, I would have to do some testing see for sure.
I will create an issue in the other project to track it.
I'm also a little curious if there's a way to make the "default" number type be a double or float instead of a decimal. I haven't dived too deeply into it but using decimal makes the arrays twice as big when they don't need to be. I'm still exploring some of the options for your generator.
Regardless, this is a great project! Thanks
It has to be decimal sadly, it was not my first choice. This is a JavaScript issue, since JS has no other number types other everything is a decimal. Moving numbers through the interop, using the UnmarshalledRuntime, causes issues typing and it looses its value.
I have spent many hours on this and it is a headache.
This hack seems to be a decent workaround to loading large arrays into BabylonJS. And it works with float arrays, too :) C#
[Inject] IJSRuntime JSRuntime { get; set; }
private IJSUnmarshalledRuntime UnmarshalledRuntime;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
UnmarshalledRuntime = (IJSUnmarshalledRuntime)JSRuntime;
}
}
------- functions used like this
var r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "positions", data.Positions);
r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "colors", data.Colors);
r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "indices", data.Indices);
r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "uvs", data.ST);
r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "uvs2", data.RowCol);
r = UnmarshalledRuntime.InvokeUnmarshalled<string, string, float[], bool>("setFast", vertexData.___guid, "uvs3", data.Radius);
Typescript:
declare var BINDING: any; //mono functions
declare var Blazor: Blazor; //blazor object
declare var Module: any; //emscripten object
declare var blazorInterop: any;
interface Blazor {
platform: Platform;
}
interface HeapLock {
release();
}
interface Platform {
start(resourceLoader: any): Promise<void>;
callEntryPoint(assemblyName: string): void;
toUint8Array(array: any): Uint8Array;
getArrayLength(array: any): number;
getArrayEntryPtr<TPtr>(array: TPtr, index: number, itemSize: number): TPtr;
getObjectFieldsBaseAddress(referenceTypedObject: any): any;
readInt16Field(baseAddress: any, fieldOffset?: number): number;
readInt32Field(baseAddress: any, fieldOffset?: number): number;
readUint64Field(baseAddress: any, fieldOffset?: number): number;
readFloatField(baseAddress: any, fieldOffset?: number): number;
readObjectField<T>(baseAddress: any, fieldOffset?: number): T;
readStringField(baseAddress: any, fieldOffset?: number, readBoolValueAsString?: boolean): string | null;
readStructField<T extends any>(baseAddress: any, fieldOffset?: number): T;
beginHeapLock(): HeapLock;
invokeWhenHeapUnlocked(callback: Function): void;
}
function setFast(root, identifier, value) {
try {
let rootName = BINDING.conv_string(root);
let identifierName = BINDING.conv_string(identifier);
let arr = toFloat32Array(value);
blazorInterop.set(rootName, identifierName, arr);
} catch (ex) {
console.log("error", ex);
}
}
function toFloat32Array(array: any): Float32Array {
const dataPtr = Blazor.platform.getArrayEntryPtr(array, 0, 4);
const length = Blazor.platform.getArrayLength(array);
return new Float32Array(Module.HEAPF32.buffer, dataPtr, length);
}
There is a huge bottleneck for me right now when I try setting decimal arrays of length > 100,000 on the
VertexData
object. It's probably due to the JSInterop layer. I took a look at your other project and it seems you useIJSUnmarshalledRuntime
only for certain getter scenarios.I wonder if it would make sense to include a new set function that has an option to use
IJSUnmarshalledRuntime
to transfer binary data. Maybe this belongs on your other project...