9 Commits

Author SHA1 Message Date
25eafaab12 workflow_dispatch 2025-03-29 18:42:37 +04:00
04a2f5b8f2 Update action to use macos-11 2025-03-29 18:39:21 +04:00
41ab98ff76 Merge pull request #3 from Bradbev/fs_support
Add support for fs.FS file system support
2025-03-29 18:38:07 +04:00
bf172f60cd Merge branch 'dev' into fs_support 2025-03-29 17:13:47 +13:00
6b65d26014 Update README.md 2024-12-16 17:54:55 +04:00
4e56ab3c9b Merge pull request #4 from BhaumikTalwar/fix-linux-linking
Fix: Linux Linking Error
2024-12-16 17:53:47 +04:00
38aa4923bc fix:Linux-Linking-Error README UPDATE 2024-12-16 13:17:24 +05:30
c8ec2b30b5 fix: Linux Linking Error 2024-12-15 04:10:21 +05:30
f50b60e8eb Add support for fs.FS file system support 2024-12-12 20:23:41 +13:00
7 changed files with 235 additions and 18 deletions

View File

@ -1,10 +1,11 @@
name: Build-AssImp
on:
workflow_dispatch:
create:
jobs:
Run-assimp-go-macos:
runs-on: macos-10.15
runs-on: macos-11
steps:
- name: Install golang 1.17
uses: actions/setup-go@v2

View File

@ -47,6 +47,27 @@ Next you will need to rename the lib to `libassimp.5.dylib` and move it to `/usr
You can use this command to do it: `sudo mkdir -p /usr/local/lib && sudo cp libassimp_darwin*.dylib /usr/local/lib/libassimp.5.dylib`
### Installing on Linux
Download the the AssImp package for your distro, or build from source and add it to your path.
> NOTE: Insatall assimp >= 3.1 for bindings to work as expected.
> Though getting the latest version is always recommended.
#### Installing on Ubuntu
You can install the Asset-Importer-Lib via apt:
```
sudo apt-get update
sudo apt-get install libassimp-dev
```
#### Installing on Arch
You can install the Asset-Importer-Lib via pacman
```
sudo pacman -S assimp
```
#### Building From Source
To build the Asset Importer Package from sorce read the [sorce build guide](https://github.com/assimp/assimp/blob/master/Build.md)
### Running assimp-go
Use `go run .` to run the simple example in `main.go` ;)

View File

@ -1,18 +1,24 @@
package asig
/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -L libs
#cgo windows,amd64 LDFLAGS: -l assimp_windows_amd64
#cgo darwin,amd64 LDFLAGS: -l assimp_darwin_amd64
#cgo darwin,arm64 LDFLAGS: -l assimp_darwin_arm64
#cgo linux CFLAGS:
#cgo windows,amd64 CFLAGS: -I .
#cgo darwin,amd64 CFLAGS: -I .
#cgo darwin,arm64 CFLAGS: -I .
#include "wrap.c"
#include <stdlib.h>
#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: -Wl,-rpath,/usr/local/lib
#include "wrap.h"
*/
import "C"
import (
"errors"
"io"
"io/fs"
"runtime"
"unsafe"
"github.com/bloeys/gglm/gglm"
@ -158,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()))
}

View File

@ -1,13 +1,17 @@
package asig
/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -L libs
#cgo windows,amd64 LDFLAGS: -l assimp_windows_amd64
#cgo darwin,arm64 LDFLAGS: -l assimp_darwin_arm64
#cgo linux CFLAGS:
#cgo windows,amd64 CFLAGS: -I .
#cgo darwin,amd64 CFLAGS: -I .
#cgo darwin,arm64 CFLAGS: -I .
#include "wrap.c"
#include <stdlib.h>
#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
#include "wrap.h"
*/
import "C"
import (

View File

@ -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
View 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

View File

@ -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)
}