Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
VkCV Framework
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Vulkan2021
VkCV Framework
Commits
d6c44973
Commit
d6c44973
authored
3 years ago
by
Trevor Hollmann
Browse files
Options
Downloads
Patches
Plain Diff
[
#26
] Fix formatting and remove obsolete comments.
parent
85e623e6
No related branches found
No related tags found
1 merge request
!19
Resolve "Asset Loading"
Pipeline
#25125
passed
3 years ago
Stage: build
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+109
-156
109 additions, 156 deletions
modules/asset_loader/src/vkcv/asset/asset_loader.cpp
with
109 additions
and
156 deletions
modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+
109
−
156
View file @
d6c44973
#include
"vkcv/asset/asset_loader.hpp"
#include
<iostream>
#include
<string.h>
// memcpy(3)
...
...
@@ -7,145 +6,102 @@
namespace
vkcv
::
asset
{
/**
* convert the accessor type from the fx-gltf library to an unsigned int
* @param type
* @return unsigned integer representation
*/
uint8_t
convertTypeToInt
(
const
fx
::
gltf
::
Accessor
::
Type
type
){
switch
(
type
){
case
fx
::
gltf
::
Accessor
::
Type
::
None
:
return
0
;
case
fx
::
gltf
::
Accessor
::
Type
::
Scalar
:
return
1
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec2
:
return
2
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec3
:
return
3
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec4
:
return
4
;
default:
return
10
;
// TODO add cases for matrices (or maybe change the type in the struct itself)
}
}
/**
* This function unrolls nested exceptions via recursion and prints them
* @param e error code
* @param path path to file that is responsible for error
*/
void
print_what
(
const
std
::
exception
&
e
,
const
std
::
string
&
path
)
{
fprintf
(
stderr
,
"ERROR loading file %s: %s
\n
"
,
path
.
c_str
(),
e
.
what
());
try
{
std
::
rethrow_if_nested
(
e
);
}
catch
(
const
std
::
exception
&
nested
)
{
std
::
cerr
<<
"nested: "
;
print_what
(
nested
,
path
);
}
}
int
loadMesh
(
const
std
::
string
&
path
,
Mesh
&
mesh
)
{
// load the gltf file using the library, return 0 if there is an
// error.
// If the library throws exceptions, catch them and maybe print an
// error, but do not pass on the exception to the caller!
// Looking at the example code of fx-gltf I would assume that
// fx::gltf::LoadFromText(); is a good starting point.
fx
::
gltf
::
Document
object
=
{};
std
::
vector
<
VertexAttribute
>
vertexAttributes
=
{};
std
::
vector
<
VertexGroup
>
vertexGroups
=
{};
std
::
vector
<
Material
>
materials
=
{};
try
{
if
(
path
.
rfind
(
".glb"
,
(
path
.
length
()
-
4
))
!=
std
::
string
::
npos
){
object
=
fx
::
gltf
::
LoadFromBinary
(
path
);
}
else
{
object
=
fx
::
gltf
::
LoadFromText
(
path
);
}
}
catch
(
const
std
::
system_error
&
err
){
// catch exception of invalid file path
print_what
(
err
,
path
);
return
0
;
}
catch
(
const
std
::
exception
&
e
){
print_what
(
e
,
path
);
return
0
;
}
// Verify that all required information can be found in the
// struct/class returned by fx-gltf (eg. check if there is exactly one
// mesh and that it has at least 3 vertices or something like that) and
// return 0 if something is missing.
// The important thing here is that we don't create an incomplete mesh
// because we start copying data before making sure all the required
// data is available.
std
::
cout
<<
"Number of Meshes loaded: "
<<
object
.
meshes
.
size
()
<<
std
::
endl
;
std
::
cout
<<
"Number of Primitives loaded: "
<<
object
.
meshes
[
0
].
primitives
.
size
()
<<
std
::
endl
;
if
(
object
.
meshes
.
size
()
!=
1
){
// only continue if exactly one mesh is loaded
return
0
;
}
fx
::
gltf
::
Mesh
const
&
objectMesh
=
object
.
meshes
[
0
];
fx
::
gltf
::
Primitive
const
&
objectPrimitive
=
objectMesh
.
primitives
[
0
];
fx
::
gltf
::
Accessor
posAccessor
;
// fill vertex attributes vector
// for some reason the loop seems to run through the attributes the wrong way round. It starts with 2 and ends on 0.
for
(
auto
const
&
attrib
:
objectPrimitive
.
attributes
){
//std::cout << "AttType: " << attrib.second << std::endl;
fx
::
gltf
::
Accessor
accessor
=
object
.
accessors
[
attrib
.
second
];
vertexAttributes
.
push_back
(
VertexAttribute
{});
// Primitive Type
if
(
attrib
.
first
==
"POSITION"
){
vertexAttributes
.
back
().
type
=
POSITION
;
posAccessor
=
accessor
;
}
else
if
(
attrib
.
first
==
"NORMAL"
){
vertexAttributes
.
back
().
type
=
NORMAL
;
}
else
if
(
attrib
.
first
==
"TEXCOORD_0"
){
vertexAttributes
.
back
().
type
=
TEXCOORD_0
;
}
else
{
return
0
;
}
// Offset
vertexAttributes
.
back
().
offset
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteOffset
;
// Length
vertexAttributes
.
back
().
length
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteLength
;
// Stride
vertexAttributes
.
back
().
stride
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteStride
;
// Component Type
vertexAttributes
.
back
().
componentType
=
static_cast
<
uint16_t
>
(
accessor
.
componentType
);
// Component Count
if
(
convertTypeToInt
(
accessor
.
type
)
!=
10
){
vertexAttributes
.
back
().
componentCount
=
convertTypeToInt
(
accessor
.
type
);
}
else
{
return
0
;
}
}
// Fill the output argument 'mesh' with the data from the loaded
// glTF file.
// Look at the structs 'Mesh', 'VertexGroup' and 'VertexAttribute'
// defined in asset_loader.hpp and compare it to the glTF cheat sheet:
// https://raw.githubusercontent.com/KhronosGroup/glTF/master/specification/2.0/figures/gltfOverview-2.0.0b.png
//
// If the fx::gltf::Document struct/class from the fx-gltf library
// don't really match our structs, we may need to re-think how our
// structs are defined (they are only based on the glTF specification).
//
// In the first iteration our goal is to simply load the vertices of a
// mesh without textures and materials. (Maybe start with our triangle
// since that does not have textures)
// Once this works, we can add support for materials/textures, but I
// wouldn't include this feature until loading of vertices+indices is
// proven to work
// indexBuffer
const
fx
::
gltf
::
Accessor
&
indexAccessor
=
object
.
accessors
[
objectPrimitive
.
indices
];
const
fx
::
gltf
::
BufferView
&
indexBufferView
=
object
.
bufferViews
[
indexAccessor
.
bufferView
];
const
fx
::
gltf
::
Buffer
&
indexBuffer
=
object
.
buffers
[
indexBufferView
.
buffer
];
/**
* convert the accessor type from the fx-gltf library to an unsigned int
* @param type
* @return unsigned integer representation
*/
uint8_t
convertTypeToInt
(
const
fx
::
gltf
::
Accessor
::
Type
type
)
{
switch
(
type
)
{
case
fx
::
gltf
::
Accessor
::
Type
::
None
:
return
0
;
case
fx
::
gltf
::
Accessor
::
Type
::
Scalar
:
return
1
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec2
:
return
2
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec3
:
return
3
;
case
fx
::
gltf
::
Accessor
::
Type
::
Vec4
:
return
4
;
default:
return
10
;
// TODO add cases for matrices (or maybe change the type in the struct itself)
}
}
/**
* This function unrolls nested exceptions via recursion and prints them
* @param e error code
* @param path path to file that is responsible for error
*/
void
print_what
(
const
std
::
exception
&
e
,
const
std
::
string
&
path
)
{
fprintf
(
stderr
,
"ERROR loading file %s: %s
\n
"
,
path
.
c_str
(),
e
.
what
());
try
{
std
::
rethrow_if_nested
(
e
);
}
catch
(
const
std
::
exception
&
nested
)
{
std
::
cerr
<<
"nested: "
;
print_what
(
nested
,
path
);
}
}
int
loadMesh
(
const
std
::
string
&
path
,
Mesh
&
mesh
)
{
fx
::
gltf
::
Document
object
=
{};
std
::
vector
<
VertexAttribute
>
vertexAttributes
=
{};
std
::
vector
<
VertexGroup
>
vertexGroups
=
{};
std
::
vector
<
Material
>
materials
=
{};
try
{
if
(
path
.
rfind
(
".glb"
,
(
path
.
length
()
-
4
))
!=
std
::
string
::
npos
)
{
object
=
fx
::
gltf
::
LoadFromBinary
(
path
);
}
else
{
object
=
fx
::
gltf
::
LoadFromText
(
path
);
}
}
catch
(
const
std
::
system_error
&
err
)
{
print_what
(
err
,
path
);
return
0
;
}
catch
(
const
std
::
exception
&
e
)
{
print_what
(
e
,
path
);
return
0
;
}
// XXX Temporary restriction: Only one mesh per glTF file
if
(
object
.
meshes
.
size
()
!=
1
)
return
0
;
fx
::
gltf
::
Mesh
const
&
objectMesh
=
object
.
meshes
[
0
];
// TODO We want to support more than one vertex group eventually...
fx
::
gltf
::
Primitive
const
&
objectPrimitive
=
objectMesh
.
primitives
[
0
];
fx
::
gltf
::
Accessor
posAccessor
;
for
(
auto
const
&
attrib
:
objectPrimitive
.
attributes
)
{
fx
::
gltf
::
Accessor
accessor
=
object
.
accessors
[
attrib
.
second
];
vertexAttributes
.
push_back
(
VertexAttribute
{});
if
(
attrib
.
first
==
"POSITION"
)
{
vertexAttributes
.
back
().
type
=
POSITION
;
posAccessor
=
accessor
;
}
else
if
(
attrib
.
first
==
"NORMAL"
)
{
vertexAttributes
.
back
().
type
=
NORMAL
;
}
else
if
(
attrib
.
first
==
"TEXCOORD_0"
)
{
vertexAttributes
.
back
().
type
=
TEXCOORD_0
;
}
else
{
return
0
;
}
vertexAttributes
.
back
().
offset
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteOffset
;
vertexAttributes
.
back
().
length
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteLength
;
vertexAttributes
.
back
().
stride
=
object
.
bufferViews
[
accessor
.
bufferView
].
byteStride
;
vertexAttributes
.
back
().
componentType
=
static_cast
<
uint16_t
>
(
accessor
.
componentType
);
if
(
convertTypeToInt
(
accessor
.
type
)
!=
10
)
{
vertexAttributes
.
back
().
componentCount
=
convertTypeToInt
(
accessor
.
type
);
}
else
{
return
0
;
}
}
// TODO consider the case where there is no index buffer (not all
// meshes have to use indexed rendering)
const
fx
::
gltf
::
Accessor
&
indexAccessor
=
object
.
accessors
[
objectPrimitive
.
indices
];
const
fx
::
gltf
::
BufferView
&
indexBufferView
=
object
.
bufferViews
[
indexAccessor
.
bufferView
];
const
fx
::
gltf
::
Buffer
&
indexBuffer
=
object
.
buffers
[
indexBufferView
.
buffer
];
std
::
vector
<
uint8_t
>
indexBufferData
;
indexBufferData
.
resize
(
indexBufferView
.
byteLength
);
{
...
...
@@ -157,16 +113,15 @@ namespace vkcv::asset {
}
}
// vertexBuffer
fx
::
gltf
::
BufferView
&
vertexBufferView
=
object
.
bufferViews
[
posAccessor
.
bufferView
];
fx
::
gltf
::
Buffer
&
vertexBuffer
=
object
.
buffers
[
vertexBufferView
.
buffer
];
fx
::
gltf
::
BufferView
&
vertexBufferView
=
object
.
bufferViews
[
posAccessor
.
bufferView
];
fx
::
gltf
::
Buffer
&
vertexBuffer
=
object
.
buffers
[
vertexBufferView
.
buffer
];
std
::
vector
<
uint8_t
>
vertexBufferData
;
vertexBufferData
.
resize
(
vertexBufferView
.
byteLength
);
{
const
size_t
off
=
vertexBufferView
.
byteOffset
;
const
void
*
const
ptr
=
((
char
*
)
vertexBuffer
.
data
.
data
())
+
off
;
if
(
!
memcpy
(
vertexBufferData
.
data
(),
ptr
,
vertexBufferView
.
byteLength
))
{
fprintf
(
stderr
,
"ERROR copying vertex buffer data.
\n
"
)
;
std
::
cerr
<<
"ERROR copying vertex buffer data.
\n
"
;
return
0
;
}
}
...
...
@@ -189,20 +144,18 @@ namespace vkcv::asset {
const
size_t
numVertexGroups
=
objectMesh
.
primitives
.
size
();
vertexGroups
.
resize
(
numVertexGroups
);
vertexGroups
[
0
]
=
{
static_cast
<
PrimitiveMode
>
(
objectPrimitive
.
mode
),
// mode
object
.
accessors
[
objectPrimitive
.
indices
].
count
,
// numIndices
posAccessor
.
count
,
// numVertices
static_cast
<
PrimitiveMode
>
(
objectPrimitive
.
mode
),
object
.
accessors
[
objectPrimitive
.
indices
].
count
,
posAccessor
.
count
,
{
indexType
,
indexBufferData
},
{
vertexBufferData
,
vertexAttributes
},
{
posAccessor
.
min
[
0
],
posAccessor
.
min
[
1
],
posAccessor
.
min
[
2
]},
// bounding box min
{
posAccessor
.
max
[
0
],
posAccessor
.
max
[
1
],
posAccessor
.
max
[
2
]},
// bounding box max
static_cast
<
uint8_t
>
(
objectPrimitive
.
material
)
// material index
};
mesh
=
{
object
.
meshes
[
0
].
name
,
vertexGroups
,
materials
};
{
posAccessor
.
min
[
0
],
posAccessor
.
min
[
1
],
posAccessor
.
min
[
2
]},
{
posAccessor
.
max
[
0
],
posAccessor
.
max
[
1
],
posAccessor
.
max
[
2
]},
static_cast
<
uint8_t
>
(
objectPrimitive
.
material
)
};
// Finally return 1 to signal that all is fine
return
1
;
}
mesh
=
{
object
.
meshes
[
0
].
name
,
vertexGroups
,
materials
};
return
1
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment