Stringer for some enums

This commit is contained in:
bloeys
2021-11-19 14:58:59 +04:00
parent e96f70d88f
commit 32c5def787
4 changed files with 464 additions and 404 deletions

View File

@ -1,379 +1,380 @@
package asig package asig
/* /*
#cgo CFLAGS: -I . #cgo CFLAGS: -I .
#cgo LDFLAGS: -L ./libs -l assimp_windows_amd64 -l IrrXML_windows_amd64 -l zlib_windows_amd64 #cgo LDFLAGS: -L ./libs -l assimp_windows_amd64 -l IrrXML_windows_amd64 -l zlib_windows_amd64
#include <stdlib.h> //Needed for C.free #include <stdlib.h> //Needed for C.free
#include <assimp/scene.h> #include <assimp/scene.h>
//Functions //Functions
struct aiScene* aiImportFile(const char* pFile, unsigned int pFlags); struct aiScene* aiImportFile(const char* pFile, unsigned int pFlags);
void aiReleaseImport(const struct aiScene* pScene); void aiReleaseImport(const struct aiScene* pScene);
const char* aiGetErrorString(); const char* aiGetErrorString();
*/ unsigned int aiGetMaterialTextureCount(const struct aiMaterial* pMat, enum aiTextureType type);
import "C" */
import ( import "C"
"errors" import (
"unsafe" "errors"
"unsafe"
"github.com/bloeys/gglm/gglm"
) "github.com/bloeys/gglm/gglm"
)
type Node struct {
} type Node struct {
}
type Animation struct {
} type Animation struct {
}
type Texture struct {
} type Texture struct {
}
type Light struct {
} type Light struct {
}
type Camera struct {
} type Camera struct {
}
type Metadata struct {
} type Metadata struct {
}
type Scene struct {
Flags SceneFlag type Scene struct {
Flags SceneFlag
RootNode *Node
Meshes []*Mesh RootNode *Node
Materials []*Material Meshes []*Mesh
Animations []*Animation Materials []*Material
Textures []*Texture Animations []*Animation
Lights []*Light Textures []*Texture
Cameras []*Camera Lights []*Light
} Cameras []*Camera
}
func ImportFile(file string, postProcessFlags PostProcess) (*Scene, error) {
func ImportFile(file string, postProcessFlags PostProcess) (*Scene, error) {
cstr := C.CString(file)
defer C.free(unsafe.Pointer(cstr)) cstr := C.CString(file)
defer C.free(unsafe.Pointer(cstr))
cs := C.aiImportFile(cstr, C.uint(postProcessFlags))
if cs == nil { cs := C.aiImportFile(cstr, C.uint(postProcessFlags))
return nil, getAiErr() if cs == nil {
} return nil, getAiErr()
defer C.aiReleaseImport(cs) }
defer C.aiReleaseImport(cs)
return parseScene(cs), nil
} return parseScene(cs), nil
}
func getAiErr() error {
return errors.New("asig error: " + C.GoString(C.aiGetErrorString())) func getAiErr() error {
} return errors.New("asig error: " + C.GoString(C.aiGetErrorString()))
}
func parseScene(cs *C.struct_aiScene) *Scene {
func parseScene(cs *C.struct_aiScene) *Scene {
s := &Scene{}
s.Flags = SceneFlag(cs.mFlags) s := &Scene{}
s.Meshes = parseMeshes(cs.mMeshes, uint(cs.mNumMeshes)) s.Flags = SceneFlag(cs.mFlags)
s.Materials = parseMaterials(cs.mMaterials, uint(cs.mNumMaterials)) s.Meshes = parseMeshes(cs.mMeshes, uint(cs.mNumMeshes))
s.Materials = parseMaterials(cs.mMaterials, uint(cs.mNumMaterials))
return s
} return s
}
func parseMeshes(cm **C.struct_aiMesh, count uint) []*Mesh {
func parseMeshes(cm **C.struct_aiMesh, count uint) []*Mesh {
if cm == nil {
return []*Mesh{} if cm == nil {
} return []*Mesh{}
}
meshes := make([]*Mesh, count)
cmeshes := unsafe.Slice(cm, count) meshes := make([]*Mesh, count)
cmeshes := unsafe.Slice(cm, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
m := &Mesh{}
m := &Mesh{}
cmesh := cmeshes[i]
vertCount := uint(cmesh.mNumVertices) cmesh := cmeshes[i]
vertCount := uint(cmesh.mNumVertices)
m.Vertices = parseVec3s(cmesh.mVertices, vertCount)
m.Normals = parseVec3s(cmesh.mNormals, vertCount) m.Vertices = parseVec3s(cmesh.mVertices, vertCount)
m.Tangents = parseVec3s(cmesh.mTangents, vertCount) m.Normals = parseVec3s(cmesh.mNormals, vertCount)
m.BitTangents = parseVec3s(cmesh.mBitangents, vertCount) m.Tangents = parseVec3s(cmesh.mTangents, vertCount)
m.BitTangents = parseVec3s(cmesh.mBitangents, vertCount)
//Color sets
m.ColorSets = parseColorSet(cmesh.mColors, vertCount) //Color sets
m.ColorSets = parseColorSet(cmesh.mColors, vertCount)
//Tex coords
m.TexCoords = parseTexCoords(cmesh.mTextureCoords, vertCount) //Tex coords
m.TexCoordChannelCount = [8]uint{} m.TexCoords = parseTexCoords(cmesh.mTextureCoords, vertCount)
for j := 0; j < len(cmesh.mTextureCoords); j++ { m.TexCoordChannelCount = [8]uint{}
for j := 0; j < len(cmesh.mTextureCoords); j++ {
//If a color set isn't available then it is nil
if cmesh.mTextureCoords[j] == nil { //If a color set isn't available then it is nil
continue if cmesh.mTextureCoords[j] == nil {
} continue
}
m.TexCoordChannelCount[j] = uint(cmeshes[j].mNumUVComponents[j])
} m.TexCoordChannelCount[j] = uint(cmeshes[j].mNumUVComponents[j])
}
//Faces
cFaces := unsafe.Slice(cmesh.mFaces, cmesh.mNumFaces) //Faces
m.Faces = make([]Face, cmesh.mNumFaces) cFaces := unsafe.Slice(cmesh.mFaces, cmesh.mNumFaces)
for j := 0; j < len(m.Faces); j++ { m.Faces = make([]Face, cmesh.mNumFaces)
for j := 0; j < len(m.Faces); j++ {
m.Faces[j] = Face{
Indices: parseUInts(cFaces[j].mIndices, uint(cFaces[j].mNumIndices)), m.Faces[j] = Face{
} Indices: parseUInts(cFaces[j].mIndices, uint(cFaces[j].mNumIndices)),
} }
}
//Other
m.Bones = parseBones(cmesh.mBones, uint(cmesh.mNumBones)) //Other
m.AnimMeshes = parseAnimMeshes(cmesh.mAnimMeshes, uint(cmesh.mNumAnimMeshes)) m.Bones = parseBones(cmesh.mBones, uint(cmesh.mNumBones))
m.AABB = AABB{ m.AnimMeshes = parseAnimMeshes(cmesh.mAnimMeshes, uint(cmesh.mNumAnimMeshes))
Min: parseVec3(&cmesh.mAABB.mMin), m.AABB = AABB{
Max: parseVec3(&cmesh.mAABB.mMax), Min: parseVec3(&cmesh.mAABB.mMin),
} Max: parseVec3(&cmesh.mAABB.mMax),
}
m.MorphMethod = MorphMethod(cmesh.mMethod)
m.MaterialIndex = uint(cmesh.mMaterialIndex) m.MorphMethod = MorphMethod(cmesh.mMethod)
m.Name = parseAiString(cmesh.mName) m.MaterialIndex = uint(cmesh.mMaterialIndex)
m.Name = parseAiString(cmesh.mName)
meshes[i] = m
} meshes[i] = m
}
return meshes
} return meshes
}
func parseVec3(cv *C.struct_aiVector3D) gglm.Vec3 {
func parseVec3(cv *C.struct_aiVector3D) gglm.Vec3 {
if cv == nil {
return gglm.Vec3{} if cv == nil {
} return gglm.Vec3{}
}
return gglm.Vec3{
Data: [3]float32{ return gglm.Vec3{
float32(cv.x), Data: [3]float32{
float32(cv.y), float32(cv.x),
float32(cv.z), float32(cv.y),
}, float32(cv.z),
} },
} }
}
func parseAnimMeshes(cam **C.struct_aiAnimMesh, count uint) []*AnimMesh {
func parseAnimMeshes(cam **C.struct_aiAnimMesh, count uint) []*AnimMesh {
if cam == nil {
return []*AnimMesh{} if cam == nil {
} return []*AnimMesh{}
}
animMeshes := make([]*AnimMesh, count)
cAnimMeshes := unsafe.Slice(cam, count) animMeshes := make([]*AnimMesh, count)
cAnimMeshes := unsafe.Slice(cam, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
m := cAnimMeshes[i]
animMeshes[i] = &AnimMesh{ m := cAnimMeshes[i]
Name: parseAiString(m.mName), animMeshes[i] = &AnimMesh{
Vertices: parseVec3s(m.mVertices, uint(m.mNumVertices)), Name: parseAiString(m.mName),
Normals: parseVec3s(m.mNormals, uint(m.mNumVertices)), Vertices: parseVec3s(m.mVertices, uint(m.mNumVertices)),
Tangents: parseVec3s(m.mTangents, uint(m.mNumVertices)), Normals: parseVec3s(m.mNormals, uint(m.mNumVertices)),
BitTangents: parseVec3s(m.mBitangents, uint(m.mNumVertices)), Tangents: parseVec3s(m.mTangents, uint(m.mNumVertices)),
Colors: parseColorSet(m.mColors, uint(m.mNumVertices)), BitTangents: parseVec3s(m.mBitangents, uint(m.mNumVertices)),
TexCoords: parseTexCoords(m.mTextureCoords, uint(m.mNumVertices)), Colors: parseColorSet(m.mColors, uint(m.mNumVertices)),
Weight: float32(m.mWeight), TexCoords: parseTexCoords(m.mTextureCoords, uint(m.mNumVertices)),
} Weight: float32(m.mWeight),
} }
}
return animMeshes
} return animMeshes
}
func parseTexCoords(ctc [MaxTexCoords]*C.struct_aiVector3D, vertCount uint) [MaxTexCoords][]gglm.Vec3 {
func parseTexCoords(ctc [MaxTexCoords]*C.struct_aiVector3D, vertCount uint) [MaxTexCoords][]gglm.Vec3 {
texCoords := [MaxTexCoords][]gglm.Vec3{}
texCoords := [MaxTexCoords][]gglm.Vec3{}
for j := 0; j < len(ctc); j++ {
for j := 0; j < len(ctc); j++ {
//If a color set isn't available then it is nil
if ctc[j] == nil { //If a color set isn't available then it is nil
continue if ctc[j] == nil {
} continue
}
texCoords[j] = parseVec3s(ctc[j], vertCount)
} texCoords[j] = parseVec3s(ctc[j], vertCount)
}
return texCoords
} return texCoords
}
func parseColorSet(cc [MaxColorSets]*C.struct_aiColor4D, vertCount uint) [MaxColorSets][]gglm.Vec4 {
func parseColorSet(cc [MaxColorSets]*C.struct_aiColor4D, vertCount uint) [MaxColorSets][]gglm.Vec4 {
colorSet := [MaxColorSets][]gglm.Vec4{}
for j := 0; j < len(cc); j++ { colorSet := [MaxColorSets][]gglm.Vec4{}
for j := 0; j < len(cc); j++ {
//If a color set isn't available then it is nil
if cc[j] == nil { //If a color set isn't available then it is nil
continue if cc[j] == nil {
} continue
}
colorSet[j] = parseColors(cc[j], vertCount)
} colorSet[j] = parseColors(cc[j], vertCount)
}
return colorSet
} return colorSet
}
func parseBones(cbs **C.struct_aiBone, count uint) []*Bone {
func parseBones(cbs **C.struct_aiBone, count uint) []*Bone {
if cbs == nil {
return []*Bone{} if cbs == nil {
} return []*Bone{}
}
bones := make([]*Bone, count)
cbones := unsafe.Slice(cbs, count) bones := make([]*Bone, count)
cbones := unsafe.Slice(cbs, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
cBone := cbones[i]
bones[i] = &Bone{ cBone := cbones[i]
Name: parseAiString(cBone.mName), bones[i] = &Bone{
Weights: parseVertexWeights(cBone.mWeights, uint(cBone.mNumWeights)), Name: parseAiString(cBone.mName),
OffsetMatrix: parseMat4(&cBone.mOffsetMatrix), Weights: parseVertexWeights(cBone.mWeights, uint(cBone.mNumWeights)),
} OffsetMatrix: parseMat4(&cBone.mOffsetMatrix),
} }
}
return bones
} return bones
}
func parseMat4(cm4 *C.struct_aiMatrix4x4) gglm.Mat4 {
func parseMat4(cm4 *C.struct_aiMatrix4x4) gglm.Mat4 {
if cm4 == nil {
return gglm.Mat4{} if cm4 == nil {
} return gglm.Mat4{}
}
return gglm.Mat4{
Data: [4][4]float32{ return gglm.Mat4{
{float32(cm4.a1), float32(cm4.b1), float32(cm4.c1), float32(cm4.d1)}, Data: [4][4]float32{
{float32(cm4.a2), float32(cm4.b2), float32(cm4.c2), float32(cm4.d2)}, {float32(cm4.a1), float32(cm4.b1), float32(cm4.c1), float32(cm4.d1)},
{float32(cm4.a3), float32(cm4.b3), float32(cm4.c3), float32(cm4.d3)}, {float32(cm4.a2), float32(cm4.b2), float32(cm4.c2), float32(cm4.d2)},
{float32(cm4.a4), float32(cm4.b4), float32(cm4.c4), float32(cm4.d4)}, {float32(cm4.a3), float32(cm4.b3), float32(cm4.c3), float32(cm4.d3)},
}, {float32(cm4.a4), float32(cm4.b4), float32(cm4.c4), float32(cm4.d4)},
} },
} }
}
func parseVertexWeights(cWeights *C.struct_aiVertexWeight, count uint) []VertexWeight {
func parseVertexWeights(cWeights *C.struct_aiVertexWeight, count uint) []VertexWeight {
if cWeights == nil {
return []VertexWeight{} if cWeights == nil {
} return []VertexWeight{}
}
vw := make([]VertexWeight, count)
cvw := unsafe.Slice(cWeights, count) vw := make([]VertexWeight, count)
cvw := unsafe.Slice(cWeights, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
vw[i] = VertexWeight{
VertIndex: uint(cvw[i].mVertexId), vw[i] = VertexWeight{
Weight: float32(cvw[i].mWeight), VertIndex: uint(cvw[i].mVertexId),
} Weight: float32(cvw[i].mWeight),
} }
}
return vw
} return vw
}
func parseAiString(aiString C.struct_aiString) string {
return C.GoStringN(&aiString.data[0], C.int(aiString.length)) func parseAiString(aiString C.struct_aiString) string {
} return C.GoStringN(&aiString.data[0], C.int(aiString.length))
}
func parseUInts(cui *C.uint, count uint) []uint {
func parseUInts(cui *C.uint, count uint) []uint {
if cui == nil {
return []uint{} if cui == nil {
} return []uint{}
}
uints := make([]uint, count)
cUInts := unsafe.Slice(cui, count) uints := make([]uint, count)
for i := 0; i < len(cUInts); i++ { cUInts := unsafe.Slice(cui, count)
uints[i] = uint(cUInts[i]) for i := 0; i < len(cUInts); i++ {
} uints[i] = uint(cUInts[i])
}
return uints
} return uints
}
func parseVec3s(cv *C.struct_aiVector3D, count uint) []gglm.Vec3 {
func parseVec3s(cv *C.struct_aiVector3D, count uint) []gglm.Vec3 {
if cv == nil {
return []gglm.Vec3{} if cv == nil {
} return []gglm.Vec3{}
}
carr := unsafe.Slice(cv, count)
verts := make([]gglm.Vec3, count) carr := unsafe.Slice(cv, count)
verts := make([]gglm.Vec3, count)
for i := 0; i < int(count); i++ {
verts[i] = gglm.Vec3{ for i := 0; i < int(count); i++ {
Data: [3]float32{ verts[i] = gglm.Vec3{
float32(carr[i].x), Data: [3]float32{
float32(carr[i].y), float32(carr[i].x),
float32(carr[i].z), float32(carr[i].y),
}, float32(carr[i].z),
} },
} }
}
return verts
} return verts
}
func parseColors(cv *C.struct_aiColor4D, count uint) []gglm.Vec4 {
func parseColors(cv *C.struct_aiColor4D, count uint) []gglm.Vec4 {
if cv == nil {
return []gglm.Vec4{} if cv == nil {
} return []gglm.Vec4{}
}
carr := unsafe.Slice(cv, count)
verts := make([]gglm.Vec4, count) carr := unsafe.Slice(cv, count)
verts := make([]gglm.Vec4, count)
for i := 0; i < int(count); i++ {
verts[i] = gglm.Vec4{ for i := 0; i < int(count); i++ {
Data: [4]float32{ verts[i] = gglm.Vec4{
float32(carr[i].r), Data: [4]float32{
float32(carr[i].g), float32(carr[i].r),
float32(carr[i].b), float32(carr[i].g),
float32(carr[i].a), float32(carr[i].b),
}, float32(carr[i].a),
} },
} }
}
return verts
} return verts
}
func parseMaterials(cMatsIn **C.struct_aiMaterial, count uint) []*Material {
func parseMaterials(cMatsIn **C.struct_aiMaterial, count uint) []*Material {
mats := make([]*Material, count)
cMats := unsafe.Slice(cMatsIn, count) mats := make([]*Material, count)
cMats := unsafe.Slice(cMatsIn, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
mats[i] = &Material{
Properties: parseMatProperties(cMats[i].mProperties, uint(cMats[i].mNumProperties)), mats[i] = &Material{
AllocatedStorage: uint(cMats[i].mNumAllocated), Properties: parseMatProperties(cMats[i].mProperties, uint(cMats[i].mNumProperties)),
} AllocatedStorage: uint(cMats[i].mNumAllocated),
} }
}
return mats
} return mats
}
func parseMatProperties(cMatPropsIn **C.struct_aiMaterialProperty, count uint) []*MaterialProperty {
func parseMatProperties(cMatPropsIn **C.struct_aiMaterialProperty, count uint) []*MaterialProperty {
matProps := make([]*MaterialProperty, count)
cMatProps := unsafe.Slice(cMatPropsIn, count) matProps := make([]*MaterialProperty, count)
cMatProps := unsafe.Slice(cMatPropsIn, count)
for i := 0; i < int(count); i++ {
for i := 0; i < int(count); i++ {
cmp := cMatProps[i]
cmp := cMatProps[i]
matProps[i] = &MaterialProperty{
name: parseAiString(cmp.mKey), matProps[i] = &MaterialProperty{
Semantic: TextureType(cmp.mSemantic), name: parseAiString(cmp.mKey),
Index: uint(cmp.mIndex), Semantic: TextureType(cmp.mSemantic),
TypeInfo: MatPropertyTypeInfo(cmp.mType), Index: uint(cmp.mIndex),
Data: C.GoBytes(unsafe.Pointer(cmp.mData), C.int(cmp.mDataLength)), TypeInfo: MatPropertyTypeInfo(cmp.mType),
} Data: C.GoBytes(unsafe.Pointer(cmp.mData), C.int(cmp.mDataLength)),
} }
}
return matProps
} return matProps
}

View File

@ -226,3 +226,79 @@ const (
TextureTypeDiffuseRoughness TextureType = 16 TextureTypeDiffuseRoughness TextureType = 16
TextureTypeAmbientOcclusion TextureType = 17 TextureTypeAmbientOcclusion TextureType = 17
) )
func (tp TextureType) String() string {
switch tp {
case TextureTypeNone:
return "None"
case TextureTypeDiffuse:
return "Diffuse"
case TextureTypeSpecular:
return "Specular"
case TextureTypeAmbient:
return "Ambient"
case TextureTypeAmbientOcclusion:
return "AmbientOcclusion"
case TextureTypeBaseColor:
return "BaseColor"
case TextureTypeDiffuseRoughness:
return "DiffuseRoughness"
case TextureTypeDisplacement:
return "Displacement"
case TextureTypeEmissionColor:
return "EmissionColor"
case TextureTypeEmissive:
return "Emissive"
case TextureTypeHeight:
return "Height"
case TextureTypeLightmap:
return "Lightmap"
case TextureTypeMetalness:
return "Metalness"
case TextureTypeNormal:
return "Normal"
case TextureTypeNormalCamera:
return "NormalCamera"
case TextureTypeOpacity:
return "Opacity"
case TextureTypeReflection:
return "Reflection"
case TextureTypeShininess:
return "Shininess"
case TextureTypeUnknown:
return "Unknown"
default:
return "Invalid"
}
}
type MatPropertyTypeInfo int32
const (
MatPropTypeInfoFloat32 MatPropertyTypeInfo = iota + 1
MatPropTypeInfoFloat64
MatPropTypeInfoString
MatPropTypeInfoInt32
//Simple binary buffer, content undefined. Not convertible to anything.
MatPropTypeInfoBuffer
)
func (mpti MatPropertyTypeInfo) String() string {
switch mpti {
case MatPropTypeInfoFloat32:
return "Float32"
case MatPropTypeInfoFloat64:
return "Float64"
case MatPropTypeInfoString:
return "String"
case MatPropTypeInfoInt32:
return "Int32"
case MatPropTypeInfoBuffer:
return "Buffer"
default:
return "Unknown"
}
}

View File

@ -38,15 +38,3 @@ type MaterialProperty struct {
*/ */
Data []byte Data []byte
} }
type MatPropertyTypeInfo int32
const (
MatPropTypeInfoFloat32 MatPropertyTypeInfo = iota + 1
MatPropTypeInfoFloat64
MatPropTypeInfoString
MatPropTypeInfoInt32
//Simple binary buffer, content undefined. Not convertible to anything.
MatPropTypeInfoBuffer
)

21
main.go
View File

@ -8,7 +8,7 @@ import (
func main() { func main() {
scene, err := asig.ImportFile("obj.obj", asig.PostProcessTriangulate) scene, err := asig.ImportFile("tex-cube.fbx", asig.PostProcessTriangulate)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -21,18 +21,13 @@ func main() {
} }
} }
// verts := meshes.Get(0).MVertices() for i := 0; i < len(scene.Materials); i++ {
// for i := 0; i < int(verts.Size()); i++ {
// v := verts.Get(i)
// fmt.Printf("V%v: (%v, %v, %v)\n", i, v.GetX(), v.GetY(), v.GetZ())
// }
// scene = asig.AiImportFile("obj.fbx", uint(0)) println("Mesh:", i, "; Props:", len(scene.Materials[i].Properties))
// meshes = scene.MMeshes() for j := 0; j < len(scene.Materials[i].Properties); j++ {
// verts = meshes.Get(0).MVertices() p := scene.Materials[i].Properties[j]
// for i := 0; i < int(verts.Size()); i++ { fmt.Printf("Data Type: %v; Len Bytes: %v; Texture Type: %v\n", p.TypeInfo.String(), len(p.Data), p.Semantic.String())
// v := verts.Get(i) }
// fmt.Printf("V%v: (%v, %v, %v)\n", i, v.GetX(), v.GetY(), v.GetZ()) }
// }
} }