Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e60d33385e | ||
|
|
744d2baa58 | ||
|
|
d5ca258817 | ||
|
|
b1ac3a6c7e | ||
|
|
69e56db124 | ||
|
|
13412b0898 | ||
|
|
9912bc5023 | ||
|
|
9d9e987c47 | ||
|
|
345560040b | ||
|
|
9134c1d395 | ||
|
|
cc9897316f | ||
|
|
e43580bd9a | ||
|
|
9613108cef | ||
|
|
4b29502c82 | ||
|
|
156b709556 | ||
|
|
00f51e3603 | ||
|
|
da5942d652 |
@@ -6,6 +6,17 @@ cmake_minimum_required(VERSION 2.8.11)
|
|||||||
set(TINYOBJLOADER_SOVERSION 1)
|
set(TINYOBJLOADER_SOVERSION 1)
|
||||||
set(TINYOBJLOADER_VERSION 1.0.4)
|
set(TINYOBJLOADER_VERSION 1.0.4)
|
||||||
|
|
||||||
|
#optional double precision support
|
||||||
|
option(TINYOBJLOADER_USE_DOUBLE "Build library with double precision instead of single (float)" OFF)
|
||||||
|
|
||||||
|
if(TINYOBJLOADER_USE_DOUBLE)
|
||||||
|
add_definitions(-DTINYOBJLOADER_USE_DOUBLE)
|
||||||
|
set(LIBRARY_NAME ${PROJECT_NAME}_double)
|
||||||
|
else()
|
||||||
|
set(LIBRARY_NAME ${PROJECT_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
#Folder Shortcuts
|
#Folder Shortcuts
|
||||||
set(TINYOBJLOADEREXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/examples)
|
set(TINYOBJLOADEREXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/examples)
|
||||||
|
|
||||||
@@ -38,32 +49,32 @@ option(TINYOBJLOADER_BUILD_TEST_LOADER "Build Example Loader Application" OFF)
|
|||||||
option(TINYOBJLOADER_COMPILATION_SHARED "Build as shared library" OFF)
|
option(TINYOBJLOADER_COMPILATION_SHARED "Build as shared library" OFF)
|
||||||
|
|
||||||
if(TINYOBJLOADER_COMPILATION_SHARED)
|
if(TINYOBJLOADER_COMPILATION_SHARED)
|
||||||
add_library(tinyobjloader SHARED ${tinyobjloader-Source})
|
add_library(${LIBRARY_NAME} SHARED ${tinyobjloader-Source})
|
||||||
set_target_properties(tinyobjloader PROPERTIES
|
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||||
SOVERSION ${TINYOBJLOADER_SOVERSION}
|
SOVERSION ${TINYOBJLOADER_SOVERSION}
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_library(tinyobjloader STATIC ${tinyobjloader-Source})
|
add_library(${LIBRARY_NAME} STATIC ${tinyobjloader-Source})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_target_properties(tinyobjloader PROPERTIES VERSION ${TINYOBJLOADER_VERSION})
|
set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${TINYOBJLOADER_VERSION})
|
||||||
|
|
||||||
target_include_directories(tinyobjloader INTERFACE
|
target_include_directories(${LIBRARY_NAME} INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
$<INSTALL_INTERFACE:${TINYOBJLOADER_INCLUDE_DIR}>
|
$<INSTALL_INTERFACE:${TINYOBJLOADER_INCLUDE_DIR}>
|
||||||
)
|
)
|
||||||
|
|
||||||
export(TARGETS tinyobjloader FILE ${PROJECT_NAME}-targets.cmake)
|
export(TARGETS ${LIBRARY_NAME} FILE ${PROJECT_NAME}-targets.cmake)
|
||||||
|
|
||||||
if(TINYOBJLOADER_BUILD_TEST_LOADER)
|
if(TINYOBJLOADER_BUILD_TEST_LOADER)
|
||||||
add_executable(test_loader ${tinyobjloader-Example-Source})
|
add_executable(test_loader ${tinyobjloader-Example-Source})
|
||||||
target_link_libraries(test_loader tinyobjloader)
|
target_link_libraries(test_loader ${LIBRARY_NAME})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(TINYOBJLOADER_BUILD_OBJ_STICHER "Build OBJ Sticher Application" OFF)
|
option(TINYOBJLOADER_BUILD_OBJ_STICHER "Build OBJ Sticher Application" OFF)
|
||||||
if(TINYOBJLOADER_BUILD_OBJ_STICHER)
|
if(TINYOBJLOADER_BUILD_OBJ_STICHER)
|
||||||
add_executable(obj_sticher ${tinyobjloader-examples-objsticher})
|
add_executable(obj_sticher ${tinyobjloader-examples-objsticher})
|
||||||
target_link_libraries(obj_sticher tinyobjloader)
|
target_link_libraries(obj_sticher ${LIBRARY_NAME})
|
||||||
|
|
||||||
install(TARGETS
|
install(TARGETS
|
||||||
obj_sticher
|
obj_sticher
|
||||||
@@ -76,8 +87,8 @@ endif()
|
|||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
configure_package_config_file(
|
configure_package_config_file(
|
||||||
tinyobjloader-config.cmake.in
|
${PROJECT_NAME}-config.cmake.in
|
||||||
tinyobjloader-config.cmake
|
${LIBRARY_NAME}-config.cmake
|
||||||
INSTALL_DESTINATION
|
INSTALL_DESTINATION
|
||||||
${TINYOBJLOADER_CMAKE_DIR}
|
${TINYOBJLOADER_CMAKE_DIR}
|
||||||
PATH_VARS
|
PATH_VARS
|
||||||
@@ -86,7 +97,7 @@ configure_package_config_file(
|
|||||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||||
)
|
)
|
||||||
|
|
||||||
write_basic_package_version_file(tinyobjloader-config-version.cmake
|
write_basic_package_version_file(${LIBRARY_NAME}-config-version.cmake
|
||||||
VERSION
|
VERSION
|
||||||
${TINYOBJLOADER_VERSION}
|
${TINYOBJLOADER_VERSION}
|
||||||
COMPATIBILITY
|
COMPATIBILITY
|
||||||
@@ -94,11 +105,11 @@ write_basic_package_version_file(tinyobjloader-config-version.cmake
|
|||||||
)
|
)
|
||||||
|
|
||||||
#pkg-config file
|
#pkg-config file
|
||||||
configure_file(tinyobjloader.pc.in tinyobjloader.pc @ONLY)
|
configure_file(${PROJECT_NAME}.pc.in ${LIBRARY_NAME}.pc @ONLY)
|
||||||
|
|
||||||
#Installation
|
#Installation
|
||||||
install(TARGETS
|
install(TARGETS
|
||||||
tinyobjloader
|
${LIBRARY_NAME}
|
||||||
EXPORT ${PROJECT_NAME}-targets
|
EXPORT ${PROJECT_NAME}-targets
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${TINYOBJLOADER_LIBRARY_DIR}
|
${TINYOBJLOADER_LIBRARY_DIR}
|
||||||
@@ -123,13 +134,13 @@ install(FILES
|
|||||||
${TINYOBJLOADER_DOC_DIR}
|
${TINYOBJLOADER_DOC_DIR}
|
||||||
)
|
)
|
||||||
install(FILES
|
install(FILES
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/tinyobjloader-config.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config.cmake"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/tinyobjloader-config-version.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config-version.cmake"
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${TINYOBJLOADER_CMAKE_DIR}
|
${TINYOBJLOADER_CMAKE_DIR}
|
||||||
)
|
)
|
||||||
install(FILES
|
install(FILES
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/tinyobjloader.pc"
|
"${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}.pc"
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${TINYOBJLOADER_PKGCONFIG_DIR}
|
${TINYOBJLOADER_PKGCONFIG_DIR}
|
||||||
)
|
)
|
||||||
|
|||||||
72
README.md
72
README.md
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
http://syoyo.github.io/tinyobjloader/
|
http://syoyo.github.io/tinyobjloader/
|
||||||
|
|
||||||
Tiny but powerful single file wavefront obj loader written in C++. No dependency except for C++ STL. It can parse 10M over polygons with moderate memory and time.
|
Tiny but powerful single file wavefront obj loader written in C++. No dependency except for C++ STL. It can parse over 10M polygons with moderate memory and time.
|
||||||
|
|
||||||
`tinyobjloader` is good for embedding .obj loader to your (global illumination) renderer ;-)
|
`tinyobjloader` is good for embedding .obj loader to your (global illumination) renderer ;-)
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ TinyObjLoader is successfully used in ...
|
|||||||
|
|
||||||
* [ ] Fix obj_sticker example.
|
* [ ] Fix obj_sticker example.
|
||||||
* [ ] More unit test codes.
|
* [ ] More unit test codes.
|
||||||
* [ ] Texture options
|
* [x] Texture options
|
||||||
* [ ] Normal vector generation
|
* [ ] Normal vector generation
|
||||||
* [ ] Support smoothing groups
|
* [ ] Support smoothing groups
|
||||||
|
|
||||||
@@ -107,10 +107,76 @@ Licensed under MIT license.
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Data format
|
||||||
|
|
||||||
`attrib_t` contains single and linear array of vertex data(position, normal and texcoord).
|
`attrib_t` contains single and linear array of vertex data(position, normal and texcoord).
|
||||||
Each `shape_t` does not contain vertex data but contains array index to `attrib_t`.
|
|
||||||
|
```
|
||||||
|
attrib_t::vertices => 3 floats per vertex
|
||||||
|
|
||||||
|
v[0] v[1] v[2] v[3] v[n-1]
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
| x | y | z | x | y | z | x | y | z | x | y | z | .... | x | y | z |
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
|
||||||
|
attrib_t::normals => 3 floats per vertex
|
||||||
|
|
||||||
|
n[0] n[1] n[2] n[3] n[n-1]
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
| x | y | z | x | y | z | x | y | z | x | y | z | .... | x | y | z |
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
|
||||||
|
attrib_t::texcoords => 2 floats per vertex
|
||||||
|
|
||||||
|
t[0] t[1] t[2] t[3] t[n-1]
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
| u | v | u | v | u | v | u | v | .... | u | v |
|
||||||
|
+-----------+-----------+-----------+-----------+ +-----------+
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Each `shape_t::mesh_t` does not contain vertex data but contains array index to `attrib_t`.
|
||||||
See `loader_example.cc` for more details.
|
See `loader_example.cc` for more details.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
mesh_t::indices => array of vertex indices.
|
||||||
|
|
||||||
|
+----+----+----+----+----+----+----+----+----+----+ +--------+
|
||||||
|
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-1) |
|
||||||
|
+----+----+----+----+----+----+----+----+----+----+ +--------+
|
||||||
|
|
||||||
|
Each index has an array index to attrib_t::vertices, attrib_t::normals and attrib_t::texcoords.
|
||||||
|
|
||||||
|
mesh_t::num_face_vertices => array of the number of vertices per face(e.g. 3 = triangle, 4 = quad , 5 or more = N-gons).
|
||||||
|
|
||||||
|
|
||||||
|
+---+---+---+ +---+
|
||||||
|
| 3 | 4 | 3 | ...... | 3 |
|
||||||
|
+---+---+---+ +---+
|
||||||
|
| | | |
|
||||||
|
| | | +-----------------------------------------+
|
||||||
|
| | | |
|
||||||
|
| | +------------------------------+ |
|
||||||
|
| | | |
|
||||||
|
| +------------------+ | |
|
||||||
|
| | | |
|
||||||
|
|/ |/ |/ |/
|
||||||
|
|
||||||
|
mesh_t::indices
|
||||||
|
|
||||||
|
| face[0] | face[1] | face[2] | | face[n-1] |
|
||||||
|
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
|
||||||
|
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-3) | i(n-2) | i(n-1) |
|
||||||
|
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that when `triangulate` flas is true in `tinyobj::LoadObj()` argument, `num_face_vertices` are all filled with 3(triangle).
|
||||||
|
|
||||||
|
#### Example code
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
|
#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
|
||||||
#include "tiny_obj_loader.h"
|
#include "tiny_obj_loader.h"
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* image = stbi_load(texture_filename.c_str(), &w, &h, &comp, STBI_default);
|
unsigned char* image = stbi_load(texture_filename.c_str(), &w, &h, &comp, STBI_default);
|
||||||
if (image == nullptr) {
|
if (!image) {
|
||||||
std::cerr << "Unable to load texture: " << texture_filename << std::endl;
|
std::cerr << "Unable to load texture: " << texture_filename << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -321,8 +321,12 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
|
|||||||
tc[2][0] = attrib.texcoords[2 * idx2.texcoord_index];
|
tc[2][0] = attrib.texcoords[2 * idx2.texcoord_index];
|
||||||
tc[2][1] = 1.0f - attrib.texcoords[2 * idx2.texcoord_index + 1];
|
tc[2][1] = 1.0f - attrib.texcoords[2 * idx2.texcoord_index + 1];
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Texcoordinates are not defined" << std::endl;
|
tc[0][0] = 0.0f;
|
||||||
exit(2);
|
tc[0][1] = 0.0f;
|
||||||
|
tc[1][0] = 0.0f;
|
||||||
|
tc[1][1] = 0.0f;
|
||||||
|
tc[2][0] = 0.0f;
|
||||||
|
tc[2][1] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float v[3][3];
|
float v[3][3];
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ newoption {
|
|||||||
description = "Build with ZStandard compression."
|
description = "Build with ZStandard compression."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newoption {
|
||||||
|
trigger = "clang",
|
||||||
|
description = "Use clang compiler."
|
||||||
|
}
|
||||||
|
|
||||||
|
newoption {
|
||||||
|
trigger = "asan",
|
||||||
|
description = "Enable AddressSanitizer(gcc or clang only)."
|
||||||
|
}
|
||||||
|
|
||||||
solution "objview"
|
solution "objview"
|
||||||
-- location ( "build" )
|
-- location ( "build" )
|
||||||
configurations { "Release", "Debug" }
|
configurations { "Release", "Debug" }
|
||||||
@@ -24,11 +34,20 @@ solution "objview"
|
|||||||
flags { "c++11" }
|
flags { "c++11" }
|
||||||
--buildoptions { "-std=c++11" }
|
--buildoptions { "-std=c++11" }
|
||||||
|
|
||||||
|
if _OPTIONS['clang'] then
|
||||||
|
toolset "clang"
|
||||||
|
end
|
||||||
|
|
||||||
if _OPTIONS['with-zlib'] then
|
if _OPTIONS['with-zlib'] then
|
||||||
defines { 'ENABLE_ZLIB' }
|
defines { 'ENABLE_ZLIB' }
|
||||||
links { 'z' }
|
links { 'z' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if _OPTIONS['asan'] then
|
||||||
|
buildoptions { '-fsanitize=address' }
|
||||||
|
linkoptions { '-fsanitize=address' }
|
||||||
|
end
|
||||||
|
|
||||||
if _OPTIONS['with-zstd'] then
|
if _OPTIONS['with-zstd'] then
|
||||||
print("with-zstd")
|
print("with-zstd")
|
||||||
defines { 'ENABLE_ZSTD' }
|
defines { 'ENABLE_ZSTD' }
|
||||||
@@ -110,11 +110,20 @@ const char *mmap_file(size_t *len, const char* filename)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
FILE* f = fopen(filename, "r" );
|
FILE* f = fopen(filename, "rb" );
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Failed to open file : %s\n", filename);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
long fileSize = ftell(f);
|
long fileSize = ftell(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
if (fileSize < 16) {
|
||||||
|
fprintf(stderr, "Empty or invalid .obj : %s\n", filename);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *p;
|
char *p;
|
||||||
int fd;
|
int fd;
|
||||||
@@ -122,29 +131,29 @@ const char *mmap_file(size_t *len, const char* filename)
|
|||||||
fd = open (filename, O_RDONLY);
|
fd = open (filename, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror ("open");
|
perror ("open");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat (fd, &sb) == -1) {
|
if (fstat (fd, &sb) == -1) {
|
||||||
perror ("fstat");
|
perror ("fstat");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISREG (sb.st_mode)) {
|
if (!S_ISREG (sb.st_mode)) {
|
||||||
fprintf (stderr, "%s is not a file\n", "lineitem.tbl");
|
fprintf (stderr, "%s is not a file\n", "lineitem.tbl");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = (char*)mmap (0, fileSize, PROT_READ, MAP_SHARED, fd, 0);
|
p = (char*)mmap (0, fileSize, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
|
||||||
if (p == MAP_FAILED) {
|
if (p == MAP_FAILED) {
|
||||||
perror ("mmap");
|
perror ("mmap");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close (fd) == -1) {
|
if (close (fd) == -1) {
|
||||||
perror ("close");
|
perror ("close");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*len) = fileSize;
|
(*len) = fileSize;
|
||||||
@@ -298,6 +307,7 @@ const char* get_file_data(size_t *len, const char* filename)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
data = mmap_file(&data_len, filename);
|
data = mmap_file(&data_len, filename);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*len) = data_len;
|
(*len) = data_len;
|
||||||
@@ -642,6 +652,12 @@ int main(int argc, char **argv)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data_len < 4) {
|
||||||
|
printf("Empty file\n");
|
||||||
|
exit(-1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
printf("filesize: %d\n", (int)data_len);
|
printf("filesize: %d\n", (int)data_len);
|
||||||
tinyobj_opt::LoadOption option;
|
tinyobj_opt::LoadOption option;
|
||||||
option.req_num_threads = num_threads;
|
option.req_num_threads = num_threads;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124)
|
||||||
// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43)
|
// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43)
|
||||||
// version 1.0.4 : Support multiple filenames for 'mtllib'(#112)
|
// version 1.0.4 : Support multiple filenames for 'mtllib'(#112)
|
||||||
// version 1.0.3 : Support parsing texture options(#85)
|
// version 1.0.3 : Support parsing texture options(#85)
|
||||||
@@ -53,7 +54,7 @@ namespace tinyobj {
|
|||||||
// (default on)
|
// (default on)
|
||||||
// -blendv on | off # set vertical texture blending
|
// -blendv on | off # set vertical texture blending
|
||||||
// (default on)
|
// (default on)
|
||||||
// -boost float_value # boost mip-map sharpness
|
// -boost real_value # boost mip-map sharpness
|
||||||
// -mm base_value gain_value # modify texture map values (default
|
// -mm base_value gain_value # modify texture map values (default
|
||||||
// 0 1)
|
// 0 1)
|
||||||
// # base_value = brightness,
|
// # base_value = brightness,
|
||||||
@@ -96,6 +97,14 @@ namespace tinyobj {
|
|||||||
// separately
|
// separately
|
||||||
// cube_left | cube_right
|
// cube_left | cube_right
|
||||||
|
|
||||||
|
#ifdef TINYOBJLOADER_USE_DOUBLE
|
||||||
|
//#pragma message "using double"
|
||||||
|
typedef double real_t;
|
||||||
|
#else
|
||||||
|
//#pragma message "using float"
|
||||||
|
typedef float real_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TEXTURE_TYPE_NONE, // default
|
TEXTURE_TYPE_NONE, // default
|
||||||
TEXTURE_TYPE_SPHERE,
|
TEXTURE_TYPE_SPHERE,
|
||||||
@@ -109,31 +118,31 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
texture_type_t type; // -type (default TEXTURE_TYPE_NONE)
|
texture_type_t type; // -type (default TEXTURE_TYPE_NONE)
|
||||||
float sharpness; // -boost (default 1.0?)
|
real_t sharpness; // -boost (default 1.0?)
|
||||||
float brightness; // base_value in -mm option (default 0)
|
real_t brightness; // base_value in -mm option (default 0)
|
||||||
float contrast; // gain_value in -mm option (default 1)
|
real_t contrast; // gain_value in -mm option (default 1)
|
||||||
float origin_offset[3]; // -o u [v [w]] (default 0 0 0)
|
real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0)
|
||||||
float scale[3]; // -s u [v [w]] (default 1 1 1)
|
real_t scale[3]; // -s u [v [w]] (default 1 1 1)
|
||||||
float turbulence[3]; // -t u [v [w]] (default 0 0 0)
|
real_t turbulence[3]; // -t u [v [w]] (default 0 0 0)
|
||||||
// int texture_resolution; // -texres resolution (default = ?) TODO
|
// int texture_resolution; // -texres resolution (default = ?) TODO
|
||||||
bool clamp; // -clamp (default false)
|
bool clamp; // -clamp (default false)
|
||||||
char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm')
|
char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm')
|
||||||
bool blendu; // -blendu (default on)
|
bool blendu; // -blendu (default on)
|
||||||
bool blendv; // -blendv (default on)
|
bool blendv; // -blendv (default on)
|
||||||
float bump_multiplier; // -bm (for bump maps only, default 1.0)
|
real_t bump_multiplier; // -bm (for bump maps only, default 1.0)
|
||||||
} texture_option_t;
|
} texture_option_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
float ambient[3];
|
real_t ambient[3];
|
||||||
float diffuse[3];
|
real_t diffuse[3];
|
||||||
float specular[3];
|
real_t specular[3];
|
||||||
float transmittance[3];
|
real_t transmittance[3];
|
||||||
float emission[3];
|
real_t emission[3];
|
||||||
float shininess;
|
real_t shininess;
|
||||||
float ior; // index of refraction
|
real_t ior; // index of refraction
|
||||||
float dissolve; // 1 == opaque; 0 == fully transparent
|
real_t dissolve; // 1 == opaque; 0 == fully transparent
|
||||||
// illumination model (see http://www.fileformat.info/format/material/)
|
// illumination model (see http://www.fileformat.info/format/material/)
|
||||||
int illum;
|
int illum;
|
||||||
|
|
||||||
@@ -157,15 +166,15 @@ typedef struct {
|
|||||||
|
|
||||||
// PBR extension
|
// PBR extension
|
||||||
// http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
|
// http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
|
||||||
float roughness; // [0, 1] default 0
|
real_t roughness; // [0, 1] default 0
|
||||||
float metallic; // [0, 1] default 0
|
real_t metallic; // [0, 1] default 0
|
||||||
float sheen; // [0, 1] default 0
|
real_t sheen; // [0, 1] default 0
|
||||||
float clearcoat_thickness; // [0, 1] default 0
|
real_t clearcoat_thickness; // [0, 1] default 0
|
||||||
float clearcoat_roughness; // [0, 1] default 0
|
real_t clearcoat_roughness; // [0, 1] default 0
|
||||||
float anisotropy; // aniso. [0, 1] default 0
|
real_t anisotropy; // aniso. [0, 1] default 0
|
||||||
float anisotropy_rotation; // anisor. [0, 1] default 0
|
real_t anisotropy_rotation; // anisor. [0, 1] default 0
|
||||||
float pad0;
|
real_t pad0;
|
||||||
float pad1;
|
real_t pad1;
|
||||||
std::string roughness_texname; // map_Pr
|
std::string roughness_texname; // map_Pr
|
||||||
std::string metallic_texname; // map_Pm
|
std::string metallic_texname; // map_Pm
|
||||||
std::string sheen_texname; // map_Ps
|
std::string sheen_texname; // map_Ps
|
||||||
@@ -187,7 +196,7 @@ typedef struct {
|
|||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
std::vector<int> intValues;
|
std::vector<int> intValues;
|
||||||
std::vector<float> floatValues;
|
std::vector<real_t> floatValues;
|
||||||
std::vector<std::string> stringValues;
|
std::vector<std::string> stringValues;
|
||||||
} tag_t;
|
} tag_t;
|
||||||
|
|
||||||
@@ -215,19 +224,19 @@ typedef struct {
|
|||||||
|
|
||||||
// Vertex attributes
|
// Vertex attributes
|
||||||
typedef struct {
|
typedef struct {
|
||||||
std::vector<float> vertices; // 'v'
|
std::vector<real_t> vertices; // 'v'
|
||||||
std::vector<float> normals; // 'vn'
|
std::vector<real_t> normals; // 'vn'
|
||||||
std::vector<float> texcoords; // 'vt'
|
std::vector<real_t> texcoords; // 'vt'
|
||||||
} attrib_t;
|
} attrib_t;
|
||||||
|
|
||||||
typedef struct callback_t_ {
|
typedef struct callback_t_ {
|
||||||
// W is optional and set to 1 if there is no `w` item in `v` line
|
// W is optional and set to 1 if there is no `w` item in `v` line
|
||||||
void (*vertex_cb)(void *user_data, float x, float y, float z, float w);
|
void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w);
|
||||||
void (*normal_cb)(void *user_data, float x, float y, float z);
|
void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z);
|
||||||
|
|
||||||
// y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in
|
// y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in
|
||||||
// `vt` line.
|
// `vt` line.
|
||||||
void (*texcoord_cb)(void *user_data, float x, float y, float z);
|
void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z);
|
||||||
|
|
||||||
// called per 'f' line. num_indices is the number of face indices(e.g. 3 for
|
// called per 'f' line. num_indices is the number of face indices(e.g. 3 for
|
||||||
// triangle, 4 for quad)
|
// triangle, 4 for quad)
|
||||||
@@ -334,6 +343,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
|
|
||||||
} // namespace tinyobj
|
} // namespace tinyobj
|
||||||
|
|
||||||
|
#endif // TINY_OBJ_LOADER_H_
|
||||||
|
|
||||||
#ifdef TINYOBJLOADER_IMPLEMENTATION
|
#ifdef TINYOBJLOADER_IMPLEMENTATION
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@@ -361,16 +372,16 @@ struct vertex_index {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct tag_sizes {
|
struct tag_sizes {
|
||||||
tag_sizes() : num_ints(0), num_floats(0), num_strings(0) {}
|
tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {}
|
||||||
int num_ints;
|
int num_ints;
|
||||||
int num_floats;
|
int num_reals;
|
||||||
int num_strings;
|
int num_strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct obj_shape {
|
struct obj_shape {
|
||||||
std::vector<float> v;
|
std::vector<real_t> v;
|
||||||
std::vector<float> vn;
|
std::vector<real_t> vn;
|
||||||
std::vector<float> vt;
|
std::vector<real_t> vt;
|
||||||
};
|
};
|
||||||
|
|
||||||
// See
|
// See
|
||||||
@@ -527,7 +538,7 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
|||||||
|
|
||||||
// NOTE: Don't use powf here, it will absolutely murder precision.
|
// NOTE: Don't use powf here, it will absolutely murder precision.
|
||||||
mantissa += static_cast<int>(*curr - 0x30) *
|
mantissa += static_cast<int>(*curr - 0x30) *
|
||||||
(read < lut_entries ? pow_lut[read] : pow(10.0, -read));
|
(read < lut_entries ? pow_lut[read] : std::pow(10.0, -read));
|
||||||
read++;
|
read++;
|
||||||
curr++;
|
curr++;
|
||||||
end_not_reached = (curr != s_end);
|
end_not_reached = (curr != s_end);
|
||||||
@@ -569,47 +580,47 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
|||||||
assemble:
|
assemble:
|
||||||
*result =
|
*result =
|
||||||
(sign == '+' ? 1 : -1) *
|
(sign == '+' ? 1 : -1) *
|
||||||
(exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa);
|
(exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) : mantissa);
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float parseFloat(const char **token, double default_value = 0.0) {
|
static inline real_t parseReal(const char **token, double default_value = 0.0) {
|
||||||
(*token) += strspn((*token), " \t");
|
(*token) += strspn((*token), " \t");
|
||||||
const char *end = (*token) + strcspn((*token), " \t\r");
|
const char *end = (*token) + strcspn((*token), " \t\r");
|
||||||
double val = default_value;
|
double val = default_value;
|
||||||
tryParseDouble((*token), end, &val);
|
tryParseDouble((*token), end, &val);
|
||||||
float f = static_cast<float>(val);
|
real_t f = static_cast<real_t>(val);
|
||||||
(*token) = end;
|
(*token) = end;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseFloat2(float *x, float *y, const char **token,
|
static inline void parseReal2(real_t *x, real_t *y, const char **token,
|
||||||
const double default_x = 0.0,
|
const double default_x = 0.0,
|
||||||
const double default_y = 0.0) {
|
const double default_y = 0.0) {
|
||||||
(*x) = parseFloat(token, default_x);
|
(*x) = parseReal(token, default_x);
|
||||||
(*y) = parseFloat(token, default_y);
|
(*y) = parseReal(token, default_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseFloat3(float *x, float *y, float *z, const char **token,
|
static inline void parseReal3(real_t *x, real_t *y, real_t *z, const char **token,
|
||||||
const double default_x = 0.0,
|
const double default_x = 0.0,
|
||||||
const double default_y = 0.0,
|
const double default_y = 0.0,
|
||||||
const double default_z = 0.0) {
|
const double default_z = 0.0) {
|
||||||
(*x) = parseFloat(token, default_x);
|
(*x) = parseReal(token, default_x);
|
||||||
(*y) = parseFloat(token, default_y);
|
(*y) = parseReal(token, default_y);
|
||||||
(*z) = parseFloat(token, default_z);
|
(*z) = parseReal(token, default_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseV(float *x, float *y, float *z, float *w,
|
static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w,
|
||||||
const char **token, const double default_x = 0.0,
|
const char **token, const double default_x = 0.0,
|
||||||
const double default_y = 0.0,
|
const double default_y = 0.0,
|
||||||
const double default_z = 0.0,
|
const double default_z = 0.0,
|
||||||
const double default_w = 1.0) {
|
const double default_w = 1.0) {
|
||||||
(*x) = parseFloat(token, default_x);
|
(*x) = parseReal(token, default_x);
|
||||||
(*y) = parseFloat(token, default_y);
|
(*y) = parseReal(token, default_y);
|
||||||
(*z) = parseFloat(token, default_z);
|
(*z) = parseReal(token, default_z);
|
||||||
(*w) = parseFloat(token, default_w);
|
(*w) = parseReal(token, default_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool parseOnOff(const char **token, bool default_value = true) {
|
static inline bool parseOnOff(const char **token, bool default_value = true) {
|
||||||
@@ -663,7 +674,7 @@ static tag_sizes parseTagTriple(const char **token) {
|
|||||||
}
|
}
|
||||||
(*token)++;
|
(*token)++;
|
||||||
|
|
||||||
ts.num_floats = atoi((*token));
|
ts.num_reals = atoi((*token));
|
||||||
(*token) += strcspn((*token), "/ \t\r");
|
(*token) += strcspn((*token), "/ \t\r");
|
||||||
if ((*token)[0] != '/') {
|
if ((*token)[0] != '/') {
|
||||||
return ts;
|
return ts;
|
||||||
@@ -788,21 +799,21 @@ static bool ParseTextureNameAndOption(std::string *texname,
|
|||||||
texopt->clamp = parseOnOff(&token, /* default */ true);
|
texopt->clamp = parseOnOff(&token, /* default */ true);
|
||||||
} else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) {
|
} else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) {
|
||||||
token += 7;
|
token += 7;
|
||||||
texopt->sharpness = parseFloat(&token, 1.0);
|
texopt->sharpness = parseReal(&token, 1.0);
|
||||||
} else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) {
|
} else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) {
|
||||||
token += 4;
|
token += 4;
|
||||||
texopt->bump_multiplier = parseFloat(&token, 1.0);
|
texopt->bump_multiplier = parseReal(&token, 1.0);
|
||||||
} else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]),
|
parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]),
|
||||||
&(texopt->origin_offset[2]), &token);
|
&(texopt->origin_offset[2]), &token);
|
||||||
} else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]),
|
parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]),
|
||||||
&token, 1.0, 1.0, 1.0);
|
&token, 1.0, 1.0, 1.0);
|
||||||
} else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]),
|
parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]),
|
||||||
&(texopt->turbulence[2]), &token);
|
&(texopt->turbulence[2]), &token);
|
||||||
} else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) {
|
} else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) {
|
||||||
token += 5;
|
token += 5;
|
||||||
@@ -817,7 +828,7 @@ static bool ParseTextureNameAndOption(std::string *texname,
|
|||||||
token = end;
|
token = end;
|
||||||
} else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) {
|
} else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) {
|
||||||
token += 4;
|
token += 4;
|
||||||
parseFloat2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0);
|
parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0);
|
||||||
} else {
|
} else {
|
||||||
// Assume texture filename
|
// Assume texture filename
|
||||||
token += strspn(token, " \t"); // skip space
|
token += strspn(token, " \t"); // skip space
|
||||||
@@ -1018,7 +1029,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
material.name = namebuf;
|
material.name = namebuf;
|
||||||
continue;
|
continue;
|
||||||
@@ -1027,8 +1038,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// ambient
|
// ambient
|
||||||
if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) {
|
if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float r, g, b;
|
real_t r, g, b;
|
||||||
parseFloat3(&r, &g, &b, &token);
|
parseReal3(&r, &g, &b, &token);
|
||||||
material.ambient[0] = r;
|
material.ambient[0] = r;
|
||||||
material.ambient[1] = g;
|
material.ambient[1] = g;
|
||||||
material.ambient[2] = b;
|
material.ambient[2] = b;
|
||||||
@@ -1038,8 +1049,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// diffuse
|
// diffuse
|
||||||
if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) {
|
if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float r, g, b;
|
real_t r, g, b;
|
||||||
parseFloat3(&r, &g, &b, &token);
|
parseReal3(&r, &g, &b, &token);
|
||||||
material.diffuse[0] = r;
|
material.diffuse[0] = r;
|
||||||
material.diffuse[1] = g;
|
material.diffuse[1] = g;
|
||||||
material.diffuse[2] = b;
|
material.diffuse[2] = b;
|
||||||
@@ -1049,8 +1060,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// specular
|
// specular
|
||||||
if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) {
|
if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float r, g, b;
|
real_t r, g, b;
|
||||||
parseFloat3(&r, &g, &b, &token);
|
parseReal3(&r, &g, &b, &token);
|
||||||
material.specular[0] = r;
|
material.specular[0] = r;
|
||||||
material.specular[1] = g;
|
material.specular[1] = g;
|
||||||
material.specular[2] = b;
|
material.specular[2] = b;
|
||||||
@@ -1061,8 +1072,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) ||
|
if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) ||
|
||||||
(token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) {
|
(token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float r, g, b;
|
real_t r, g, b;
|
||||||
parseFloat3(&r, &g, &b, &token);
|
parseReal3(&r, &g, &b, &token);
|
||||||
material.transmittance[0] = r;
|
material.transmittance[0] = r;
|
||||||
material.transmittance[1] = g;
|
material.transmittance[1] = g;
|
||||||
material.transmittance[2] = b;
|
material.transmittance[2] = b;
|
||||||
@@ -1072,15 +1083,15 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// ior(index of refraction)
|
// ior(index of refraction)
|
||||||
if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) {
|
if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.ior = parseFloat(&token);
|
material.ior = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// emission
|
// emission
|
||||||
if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) {
|
if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float r, g, b;
|
real_t r, g, b;
|
||||||
parseFloat3(&r, &g, &b, &token);
|
parseReal3(&r, &g, &b, &token);
|
||||||
material.emission[0] = r;
|
material.emission[0] = r;
|
||||||
material.emission[1] = g;
|
material.emission[1] = g;
|
||||||
material.emission[2] = b;
|
material.emission[2] = b;
|
||||||
@@ -1090,7 +1101,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// shininess
|
// shininess
|
||||||
if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) {
|
if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.shininess = parseFloat(&token);
|
material.shininess = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1104,7 +1115,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// dissolve
|
// dissolve
|
||||||
if ((token[0] == 'd' && IS_SPACE(token[1]))) {
|
if ((token[0] == 'd' && IS_SPACE(token[1]))) {
|
||||||
token += 1;
|
token += 1;
|
||||||
material.dissolve = parseFloat(&token);
|
material.dissolve = parseReal(&token);
|
||||||
|
|
||||||
if (has_tr) {
|
if (has_tr) {
|
||||||
ss << "WARN: Both `d` and `Tr` parameters defined for \""
|
ss << "WARN: Both `d` and `Tr` parameters defined for \""
|
||||||
@@ -1125,7 +1136,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// We invert value of Tr(assume Tr is in range [0, 1])
|
// We invert value of Tr(assume Tr is in range [0, 1])
|
||||||
// NOTE: Interpretation of Tr is application(exporter) dependent. For
|
// NOTE: Interpretation of Tr is application(exporter) dependent. For
|
||||||
// some application(e.g. 3ds max obj exporter), Tr = d(Issue 43)
|
// some application(e.g. 3ds max obj exporter), Tr = d(Issue 43)
|
||||||
material.dissolve = 1.0f - parseFloat(&token);
|
material.dissolve = 1.0f - parseReal(&token);
|
||||||
}
|
}
|
||||||
has_tr = true;
|
has_tr = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1134,49 +1145,49 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// PBR: roughness
|
// PBR: roughness
|
||||||
if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) {
|
if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.roughness = parseFloat(&token);
|
material.roughness = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: metallic
|
// PBR: metallic
|
||||||
if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) {
|
if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.metallic = parseFloat(&token);
|
material.metallic = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: sheen
|
// PBR: sheen
|
||||||
if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) {
|
if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.sheen = parseFloat(&token);
|
material.sheen = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: clearcoat thickness
|
// PBR: clearcoat thickness
|
||||||
if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) {
|
if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) {
|
||||||
token += 2;
|
token += 2;
|
||||||
material.clearcoat_thickness = parseFloat(&token);
|
material.clearcoat_thickness = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: clearcoat roughness
|
// PBR: clearcoat roughness
|
||||||
if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) {
|
if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) {
|
||||||
token += 4;
|
token += 4;
|
||||||
material.clearcoat_roughness = parseFloat(&token);
|
material.clearcoat_roughness = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: anisotropy
|
// PBR: anisotropy
|
||||||
if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) {
|
if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) {
|
||||||
token += 6;
|
token += 6;
|
||||||
material.anisotropy = parseFloat(&token);
|
material.anisotropy = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: anisotropy rotation
|
// PBR: anisotropy rotation
|
||||||
if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
material.anisotropy_rotation = parseFloat(&token);
|
material.anisotropy_rotation = parseReal(&token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1416,9 +1427,9 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
bool triangulate) {
|
bool triangulate) {
|
||||||
std::stringstream errss;
|
std::stringstream errss;
|
||||||
|
|
||||||
std::vector<float> v;
|
std::vector<real_t> v;
|
||||||
std::vector<float> vn;
|
std::vector<real_t> vn;
|
||||||
std::vector<float> vt;
|
std::vector<real_t> vt;
|
||||||
std::vector<tag_t> tags;
|
std::vector<tag_t> tags;
|
||||||
std::vector<std::vector<vertex_index> > faceGroup;
|
std::vector<std::vector<vertex_index> > faceGroup;
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -1460,8 +1471,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// vertex
|
// vertex
|
||||||
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float x, y, z;
|
real_t x, y, z;
|
||||||
parseFloat3(&x, &y, &z, &token);
|
parseReal3(&x, &y, &z, &token);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
v.push_back(y);
|
v.push_back(y);
|
||||||
v.push_back(z);
|
v.push_back(z);
|
||||||
@@ -1471,8 +1482,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// normal
|
// normal
|
||||||
if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) {
|
if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
float x, y, z;
|
real_t x, y, z;
|
||||||
parseFloat3(&x, &y, &z, &token);
|
parseReal3(&x, &y, &z, &token);
|
||||||
vn.push_back(x);
|
vn.push_back(x);
|
||||||
vn.push_back(y);
|
vn.push_back(y);
|
||||||
vn.push_back(z);
|
vn.push_back(z);
|
||||||
@@ -1482,8 +1493,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// texcoord
|
// texcoord
|
||||||
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
|
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
float x, y;
|
real_t x, y;
|
||||||
parseFloat2(&x, &y, &token);
|
parseReal2(&x, &y, &token);
|
||||||
vt.push_back(x);
|
vt.push_back(x);
|
||||||
vt.push_back(y);
|
vt.push_back(y);
|
||||||
continue;
|
continue;
|
||||||
@@ -1520,7 +1531,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int newMaterialId = -1;
|
int newMaterialId = -1;
|
||||||
@@ -1640,7 +1651,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
name = std::string(namebuf);
|
name = std::string(namebuf);
|
||||||
|
|
||||||
@@ -1655,7 +1666,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
tag.name = std::string(namebuf);
|
tag.name = std::string(namebuf);
|
||||||
|
|
||||||
@@ -1670,9 +1681,9 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
token += strcspn(token, "/ \t\r") + 1;
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.floatValues.resize(static_cast<size_t>(ts.num_floats));
|
tag.floatValues.resize(static_cast<size_t>(ts.num_reals));
|
||||||
for (size_t i = 0; i < static_cast<size_t>(ts.num_floats); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(ts.num_reals); ++i) {
|
||||||
tag.floatValues[i] = parseFloat(&token);
|
tag.floatValues[i] = parseReal(&token);
|
||||||
token += strcspn(token, "/ \t\r") + 1;
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1684,7 +1695,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
sscanf_s(token, "%s", stringValueBuffer,
|
sscanf_s(token, "%s", stringValueBuffer,
|
||||||
(unsigned)_countof(stringValueBuffer));
|
(unsigned)_countof(stringValueBuffer));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", stringValueBuffer);
|
std::sscanf(token, "%s", stringValueBuffer);
|
||||||
#endif
|
#endif
|
||||||
tag.stringValues[i] = stringValueBuffer;
|
tag.stringValues[i] = stringValueBuffer;
|
||||||
token += tag.stringValues[i].size() + 1;
|
token += tag.stringValues[i].size() + 1;
|
||||||
@@ -1766,7 +1777,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
// vertex
|
// vertex
|
||||||
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
if (token[0] == 'v' && IS_SPACE((token[1]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
float x, y, z, w; // w is optional. default = 1.0
|
real_t x, y, z, w; // w is optional. default = 1.0
|
||||||
parseV(&x, &y, &z, &w, &token);
|
parseV(&x, &y, &z, &w, &token);
|
||||||
if (callback.vertex_cb) {
|
if (callback.vertex_cb) {
|
||||||
callback.vertex_cb(user_data, x, y, z, w);
|
callback.vertex_cb(user_data, x, y, z, w);
|
||||||
@@ -1777,8 +1788,8 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
// normal
|
// normal
|
||||||
if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) {
|
if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
float x, y, z;
|
real_t x, y, z;
|
||||||
parseFloat3(&x, &y, &z, &token);
|
parseReal3(&x, &y, &z, &token);
|
||||||
if (callback.normal_cb) {
|
if (callback.normal_cb) {
|
||||||
callback.normal_cb(user_data, x, y, z);
|
callback.normal_cb(user_data, x, y, z);
|
||||||
}
|
}
|
||||||
@@ -1788,8 +1799,8 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
// texcoord
|
// texcoord
|
||||||
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
|
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
float x, y, z; // y and z are optional. default = 0.0
|
real_t x, y, z; // y and z are optional. default = 0.0
|
||||||
parseFloat3(&x, &y, &z, &token);
|
parseReal3(&x, &y, &z, &token);
|
||||||
if (callback.texcoord_cb) {
|
if (callback.texcoord_cb) {
|
||||||
callback.texcoord_cb(user_data, x, y, z);
|
callback.texcoord_cb(user_data, x, y, z);
|
||||||
}
|
}
|
||||||
@@ -1831,7 +1842,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
sscanf_s(token, "%s", namebuf,
|
sscanf_s(token, "%s", namebuf,
|
||||||
static_cast<unsigned int>(_countof(namebuf)));
|
static_cast<unsigned int>(_countof(namebuf)));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int newMaterialId = -1;
|
int newMaterialId = -1;
|
||||||
@@ -1945,7 +1956,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
std::string object_name = std::string(namebuf);
|
std::string object_name = std::string(namebuf);
|
||||||
|
|
||||||
@@ -1965,7 +1976,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", namebuf);
|
std::sscanf(token, "%s", namebuf);
|
||||||
#endif
|
#endif
|
||||||
tag.name = std::string(namebuf);
|
tag.name = std::string(namebuf);
|
||||||
|
|
||||||
@@ -1980,9 +1991,9 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
token += strcspn(token, "/ \t\r") + 1;
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.floatValues.resize(static_cast<size_t>(ts.num_floats));
|
tag.floatValues.resize(static_cast<size_t>(ts.num_reals));
|
||||||
for (size_t i = 0; i < static_cast<size_t>(ts.num_floats); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(ts.num_reals); ++i) {
|
||||||
tag.floatValues[i] = parseFloat(&token);
|
tag.floatValues[i] = parseReal(&token);
|
||||||
token += strcspn(token, "/ \t\r") + 1;
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1994,7 +2005,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
sscanf_s(token, "%s", stringValueBuffer,
|
sscanf_s(token, "%s", stringValueBuffer,
|
||||||
(unsigned)_countof(stringValueBuffer));
|
(unsigned)_countof(stringValueBuffer));
|
||||||
#else
|
#else
|
||||||
sscanf(token, "%s", stringValueBuffer);
|
std::sscanf(token, "%s", stringValueBuffer);
|
||||||
#endif
|
#endif
|
||||||
tag.stringValues[i] = stringValueBuffer;
|
tag.stringValues[i] = stringValueBuffer;
|
||||||
token += tag.stringValues[i].size() + 1;
|
token += tag.stringValues[i].size() + 1;
|
||||||
@@ -2016,5 +2027,3 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
|
|||||||
} // namespace tinyobj
|
} // namespace tinyobj
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TINY_OBJ_LOADER_H_
|
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ set(TINYOBJLOADER_VERSION "@TINYOBJLOADER_VERSION@")
|
|||||||
|
|
||||||
set_and_check(TINYOBJLOADER_INCLUDE_DIRS "@PACKAGE_TINYOBJLOADER_INCLUDE_DIR@")
|
set_and_check(TINYOBJLOADER_INCLUDE_DIRS "@PACKAGE_TINYOBJLOADER_INCLUDE_DIR@")
|
||||||
set_and_check(TINYOBJLOADER_LIBRARY_DIRS "@PACKAGE_TINYOBJLOADER_LIBRARY_DIR@")
|
set_and_check(TINYOBJLOADER_LIBRARY_DIRS "@PACKAGE_TINYOBJLOADER_LIBRARY_DIR@")
|
||||||
set(TINYOBJLOADER_LIBRARIES tinyobjloader)
|
set(TINYOBJLOADER_LIBRARIES @LIBRARY_NAME@)
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ Name: @PROJECT_NAME@
|
|||||||
Description: Tiny but powerful single file wavefront obj loader
|
Description: Tiny but powerful single file wavefront obj loader
|
||||||
URL: https://syoyo.github.io/tinyobjloader/
|
URL: https://syoyo.github.io/tinyobjloader/
|
||||||
Version: @TINYOBJLOADER_VERSION@
|
Version: @TINYOBJLOADER_VERSION@
|
||||||
Libs: -L${libdir} -ltinyobjloader
|
Libs: -L${libdir} -l@LIBRARY_NAME@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|||||||
Reference in New Issue
Block a user