Open Verschwiegener opened 5 months ago
Similar issue here, but with loading an .obj file
I just ran into this issue (or at least a very similar one) trying to load an .obj
file and having the JVM crash when trying to do
memCopy(memAddress(data), pBuffer, max * size);
I managed to fix my issue with it crashing by making my ByteBuffer
with MemoryUtil.memAlloc
(instead of ByteBuffer.wrap
which I was using before)
Here's what my equivilant of public static ByteBuffer ioResourceToByteBuffer(String resource, int bufferSize)
looks like
/** Allocates a new byte buffer which must be freed with MemoryUtil.memFree */
public static ByteBuffer resourceToByteBuffer(String fileName) throws FileNotFoundException, IOException {
try(InputStream in = Main.class.getResourceAsStream(fileName)) {
var buf = MemoryUtil.memAlloc( in.available() );
while(in.available() > 0)
buf.put(in.readNBytes(8192));
return buf;
}
}
If you do this then you also have to call MemoryUtil.memFree
, so I changed my AIFileIO
to track open files by address with a HashMap so I can make sure it frees the memory
So now it looks like this:
protected static AIFileIO makeFileIO() {
// keep track of file addresses & buffers
HashMap<Long, ByteBuffer> opened = new HashMap<>();
return AIFileIO.create()
.OpenProc((pFileIO, fileName, openMode) -> {
ByteBuffer data;
String fileNameUtf8 = memUTF8(fileName);
try {
data = FileUtils.resourceToByteBuffer(fileNameUtf8);
data.position(0); //File read error when reading the next file if you don't set this to 0
} catch (IOException e) {
throw new RuntimeException("Could not open file: " + fileNameUtf8);
}
var address = AIFile.create()
.ReadProc((pFile, pBuffer, size, count) -> {
long max = Math.min(data.remaining() / size, count);
memCopy(memAddress(data), pBuffer, max * size);
data.position(data.position() + (int) (max * size));
return max;
})
.SeekProc((pFile, offset, origin) -> {
if (origin == Assimp.aiOrigin_CUR) {
data.position(data.position() + (int) offset);
} else if (origin == Assimp.aiOrigin_SET) {
data.position((int) offset);
} else if (origin == Assimp.aiOrigin_END) {
data.position(data.limit() + (int) offset);
}
return 0;
})
.FileSizeProc(pFile -> data.limit())
.address();
opened.put(address, data);
return address;
})
.CloseProc((pFileIO, pFile) -> {
AIFile aiFile = AIFile.create(pFile);
// find and free buffer
var buf = opened.get(pFile);
if(buf != null)
MemoryUtil.memFree(buf);
else
System.err.println("Buffer not closed!");
aiFile.ReadProc().free();
aiFile.SeekProc().free();
aiFile.FileSizeProc().free();
});
}
If there's a better way to handle the buffers/AIFileIO I'm curious to know, but I'm happy I got it working at least.
Version
3.3.3
Platform
Linux x64
JDK
OpenJDK-17-Amd64
Module
Assimp
Bug description
Im trying to load a .3ds File with Assimp but the code crashes in Native Code, the Model Load code is a slightly changed Version of the Code in the Assimp Example. I checked that the Path to the 3ds File is valid and the Code does work with OBJ Files.
Any help would be appreciated :)
Model Load Code:
Stacktrace or crash log output