mirror of
https://github.com/bloeys/assimp-go.git
synced 2025-12-29 08:28:20 +00:00
Merge pull request #3 from Bradbev/fs_support
Add support for fs.FS file system support
This commit is contained in:
123
asig/asig.go
123
asig/asig.go
@ -9,14 +9,16 @@ package asig
|
||||
#cgo linux LDFLAGS: -lassimp
|
||||
#cgo windows,amd64 LDFLAGS: -L libs -l assimp_windows_amd64
|
||||
#cgo darwin,amd64 LDFLAGS: -L libs -l assimp_darwin_amd64
|
||||
#cgo darwin,arm64 LDFLAGS: -L libs -l assimp_darwin_arm64
|
||||
#cgo darwin,arm64 LDFLAGS: -Wl,-rpath,/usr/local/lib
|
||||
|
||||
#include "wrap.c"
|
||||
#include <stdlib.h>
|
||||
#include "wrap.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
@ -162,6 +164,121 @@ func ImportFile(file string, postProcessFlags PostProcess) (s *Scene, release fu
|
||||
return s, func() { s.releaseCResources() }, nil
|
||||
}
|
||||
|
||||
//export go_aiFileOpenProc
|
||||
func go_aiFileOpenProc(io *C.struct_aiFileIO, name *C.char, flags *C.char) *C.struct_aiFile {
|
||||
fsWrapper := (*fsWrapper)(unsafe.Pointer(io.UserData))
|
||||
|
||||
file, err := fsWrapper.fsys.Open(C.GoString(name))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
fsWrapper.Pin(&file)
|
||||
|
||||
ret := &C.struct_aiFile{
|
||||
ReadProc: (C.aiFileReadProc)(C.cgo_aiFileReadProc),
|
||||
WriteProc: (C.aiFileWriteProc)(C.cgo_aiFileWriteProc),
|
||||
TellProc: (C.aiFileTellProc)(C.cgo_aiFileTellProc),
|
||||
FileSizeProc: (C.aiFileTellProc)(C.cgo_aiFileFileSizeProc),
|
||||
SeekProc: (C.aiFileSeek)(C.cgo_aiFileSeekProc),
|
||||
FlushProc: (C.aiFileFlushProc)(C.cgo_aiFileFlushProc),
|
||||
UserData: (*C.char)(unsafe.Pointer(&file)),
|
||||
}
|
||||
fsWrapper.Pin(ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
//export go_aiFileCloseProc
|
||||
func go_aiFileCloseProc(io *C.struct_aiFileIO, file *C.struct_aiFile) {
|
||||
f := *(*fs.File)(unsafe.Pointer(file.UserData))
|
||||
f.Close()
|
||||
}
|
||||
|
||||
//export go_aiFileReadProc
|
||||
func go_aiFileReadProc(file *C.struct_aiFile, buffer *C.char, size C.size_t, count C.size_t) C.size_t {
|
||||
f := *(*fs.File)(unsafe.Pointer(file.UserData))
|
||||
slice := unsafe.Slice((*byte)(unsafe.Pointer(buffer)), size*count)
|
||||
|
||||
n, err := f.Read(slice)
|
||||
if err != nil {
|
||||
return (C.size_t)(0)
|
||||
}
|
||||
return (C.size_t)(n)
|
||||
}
|
||||
|
||||
//export go_aiFileWriteProc
|
||||
func go_aiFileWriteProc(file *C.struct_aiFile, buffer *C.char, size C.size_t, count C.size_t) C.size_t {
|
||||
panic("aiFileWrite not supported")
|
||||
}
|
||||
|
||||
//export go_aiFileFileSizeProc
|
||||
func go_aiFileFileSizeProc(file *C.struct_aiFile) C.size_t {
|
||||
f := *(*fs.File)(unsafe.Pointer(file.UserData))
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return (C.size_t)(info.Size())
|
||||
}
|
||||
|
||||
//export go_aiFileFlushProc
|
||||
func go_aiFileFlushProc(file *C.struct_aiFile) {
|
||||
panic("aiFileFlush not supported")
|
||||
}
|
||||
|
||||
//export go_aiFileTellProc
|
||||
func go_aiFileTellProc(file *C.struct_aiFile) C.size_t {
|
||||
panic("aiFileTell not supported")
|
||||
}
|
||||
|
||||
//export go_aiFileSeekProc
|
||||
func go_aiFileSeekProc(file *C.struct_aiFile, offset C.size_t, origin C.enum_aiOrigin) C.enum_aiReturn {
|
||||
f := *(*fs.File)(unsafe.Pointer(file.UserData))
|
||||
if s, ok := f.(io.Seeker); ok {
|
||||
_, err := s.Seek(int64(offset), int(origin))
|
||||
if err == nil {
|
||||
return aiReturnSuccess
|
||||
}
|
||||
}
|
||||
return aiReturnFailure
|
||||
}
|
||||
|
||||
type fsWrapper struct {
|
||||
pinnedMemory runtime.Pinner
|
||||
fsys fs.FS
|
||||
}
|
||||
|
||||
func (fws *fsWrapper) Pin(pointer interface{}) {
|
||||
fws.pinnedMemory.Pin(pointer)
|
||||
}
|
||||
|
||||
func ImportFileEx(file string, postProcessFlags PostProcess, fsys fs.FS) (s *Scene, release func(), err error) {
|
||||
cstr := C.CString(file)
|
||||
defer C.free(unsafe.Pointer(cstr))
|
||||
|
||||
wrapper := &fsWrapper{
|
||||
pinnedMemory: runtime.Pinner{},
|
||||
fsys: fsys,
|
||||
}
|
||||
wrapper.Pin(wrapper)
|
||||
defer wrapper.pinnedMemory.Unpin()
|
||||
|
||||
cio := &C.struct_aiFileIO{
|
||||
OpenProc: (C.aiFileOpenProc)(C.cgo_aiFileOpenProc),
|
||||
CloseProc: (C.aiFileCloseProc)(C.cgo_aiFileCloseProc),
|
||||
UserData: (*C.char)(unsafe.Pointer(wrapper)),
|
||||
}
|
||||
wrapper.Pin(cio)
|
||||
|
||||
cs := C.aiImportFileEx(cstr, C.uint(postProcessFlags), cio)
|
||||
if cs == nil {
|
||||
return nil, func() {}, getAiErr()
|
||||
}
|
||||
|
||||
s = parseScene(cs)
|
||||
return s, func() { s.releaseCResources() }, nil
|
||||
}
|
||||
|
||||
func getAiErr() error {
|
||||
return errors.New("asig error: " + C.GoString(C.aiGetErrorString()))
|
||||
}
|
||||
|
||||
@ -11,8 +11,7 @@ package asig
|
||||
#cgo darwin,amd64 LDFLAGS: -L libs -l assimp_darwin_amd64
|
||||
#cgo darwin,arm64 LDFLAGS: -L libs -l assimp_darwin_arm64
|
||||
|
||||
#include "wrap.c"
|
||||
#include <stdlib.h>
|
||||
#include "wrap.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
|
||||
53
asig/wrap.c
53
asig/wrap.c
@ -1,3 +1,50 @@
|
||||
#include <assimp/cimport.h> // Plain-C interface
|
||||
#include <assimp/scene.h> // Output data structure
|
||||
#include <assimp/postprocess.h>
|
||||
#include "wrap.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern C_STRUCT aiFile *go_aiFileOpenProc(C_STRUCT aiFileIO *io, char *name, char *flags);
|
||||
C_STRUCT aiFile *cgo_aiFileOpenProc(C_STRUCT aiFileIO *io, const char *name, const char *flags)
|
||||
{
|
||||
return go_aiFileOpenProc(io, (char *)name, (char *)flags);
|
||||
}
|
||||
|
||||
extern void go_aiFileCloseProc(C_STRUCT aiFileIO *io, C_STRUCT aiFile *file);
|
||||
void cgo_aiFileCloseProc(C_STRUCT aiFileIO *io, C_STRUCT aiFile *file)
|
||||
{
|
||||
go_aiFileCloseProc(io, file);
|
||||
}
|
||||
|
||||
extern size_t go_aiFileWriteProc(C_STRUCT aiFile *file, const char *buffer, size_t size, size_t count);
|
||||
size_t cgo_aiFileWriteProc(C_STRUCT aiFile *file, const char *buffer, size_t size, size_t count)
|
||||
{
|
||||
return go_aiFileWriteProc(file, (char *)buffer, size, count);
|
||||
}
|
||||
|
||||
extern size_t go_aiFileReadProc(C_STRUCT aiFile *, char *, size_t, size_t);
|
||||
size_t cgo_aiFileReadProc(C_STRUCT aiFile *file, char *buffer, size_t size, size_t count)
|
||||
{
|
||||
return go_aiFileReadProc(file, buffer, size, count);
|
||||
}
|
||||
|
||||
extern size_t go_aiFileTellProc(C_STRUCT aiFile *file);
|
||||
size_t cgo_aiFileTellProc(C_STRUCT aiFile *file)
|
||||
{
|
||||
return go_aiFileTellProc(file);
|
||||
}
|
||||
|
||||
extern size_t go_aiFileFileSizeProc(C_STRUCT aiFile *file);
|
||||
size_t cgo_aiFileFileSizeProc(C_STRUCT aiFile *file)
|
||||
{
|
||||
return go_aiFileFileSizeProc(file);
|
||||
}
|
||||
|
||||
extern void go_aiFileFlushProc(C_STRUCT aiFile *file);
|
||||
void cgo_aiFileFlushProc(C_STRUCT aiFile *file)
|
||||
{
|
||||
go_aiFileFlushProc(file);
|
||||
}
|
||||
|
||||
extern C_ENUM aiReturn go_aiFileSeekProc(C_STRUCT aiFile *file, size_t offset, C_ENUM aiOrigin origin);
|
||||
C_ENUM aiReturn cgo_aiFileSeekProc(C_STRUCT aiFile *file, size_t offset, C_ENUM aiOrigin origin)
|
||||
{
|
||||
return go_aiFileSeekProc(file, offset, origin);
|
||||
}
|
||||
|
||||
20
asig/wrap.h
Normal file
20
asig/wrap.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef WRAP_H
|
||||
#define WRAP_H
|
||||
|
||||
#include <assimp/cimport.h> // Plain-C interface
|
||||
#include <assimp/cfileio.h> // Plain-C interface
|
||||
#include <assimp/scene.h> // Output data structure
|
||||
#include <assimp/postprocess.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
C_STRUCT aiFile *cgo_aiFileOpenProc(C_STRUCT aiFileIO *io, const char *name, const char *flags);
|
||||
void cgo_aiFileCloseProc(C_STRUCT aiFileIO *io, C_STRUCT aiFile *file);
|
||||
|
||||
size_t cgo_aiFileWriteProc(C_STRUCT aiFile *, const char *, size_t, size_t);
|
||||
size_t cgo_aiFileReadProc(C_STRUCT aiFile *, char *, size_t, size_t);
|
||||
size_t cgo_aiFileTellProc(C_STRUCT aiFile *);
|
||||
size_t cgo_aiFileFileSizeProc(C_STRUCT aiFile *);
|
||||
void cgo_aiFileFlushProc(C_STRUCT aiFile *);
|
||||
C_ENUM aiReturn cgo_aiFileSeekProc(C_STRUCT aiFile *, size_t, C_ENUM aiOrigin);
|
||||
|
||||
#endif
|
||||
5
main.go
5
main.go
@ -4,13 +4,16 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image/png"
|
||||
"os"
|
||||
|
||||
"github.com/bloeys/assimp-go/asig"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
scene, release, err := asig.ImportFile("obj.obj", asig.PostProcessTriangulate|asig.PostProcessJoinIdenticalVertices)
|
||||
//scene, release, err := asig.ImportFile("obj.obj", asig.PostProcessTriangulate|asig.PostProcessJoinIdenticalVertices)
|
||||
fsys := os.DirFS(".")
|
||||
scene, release, err := asig.ImportFileEx("obj.obj", asig.PostProcessTriangulate|asig.PostProcessJoinIdenticalVertices, fsys)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user