├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── LICENSE.txt
├── README.md
├── helpers
├── FindUtils.cmake
├── GL
│ ├── glew.h
│ ├── glxew.h
│ └── wglew.h
├── Helpers.cmake
├── Packages.cmake
├── camera.cpp
├── camera.h
├── directory.cpp
├── directory.h
├── file_png.cpp
├── file_png.h
├── file_tga.cpp
├── file_tga.h
├── glew.c
├── main.h
├── main_win.cpp
├── main_x11.cpp
├── nvToolsExt64_1.dll
├── nv_gui.cpp
├── nv_gui.h
├── string_helper.cpp
├── string_helper.h
├── vec.cpp
└── vec.h
├── joints.cpp
├── joints.h
├── main.cpp
└── quaternion.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows thumbnail cache files
2 | Thumbs.db
3 | ehthumbs.db
4 | ehthumbs_vista.db
5 |
6 | # Folder config file
7 | Desktop.ini
8 |
9 | # Recycle Bin used on file shares
10 | $RECYCLE.BIN/
11 |
12 | # Windows Installer files
13 | *.cab
14 | *.msi
15 | *.msm
16 | *.msp
17 |
18 | # Windows shortcuts
19 | *.lnk
20 |
21 | # =========================
22 | # Operating System Files
23 | # =========================
24 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 | set(PROJNAME Invk)
3 | Project(${PROJNAME})
4 | Message(STATUS "-------------------------------")
5 | Message(STATUS "Processing Project ${PROJNAME}:")
6 |
7 | ####################################################################################
8 | # Bootstrap
9 | #
10 | set( BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
11 | find_path ( HELPERS_PATH "Helpers.cmake" HINTS ${BASE_DIRECTORY}/../libraries/helpers ${BASE_DIRECTORY}/helpers ${CMAKE_HELPERS_PATH} )
12 | if ( ${HELPERS_PATH} STREQUAL "HELPERS-NOTFOUND" )
13 | message ( FATAL_ERROR "\n Please set the CMAKE_HELPERS_PATH to for cmake helpers." )
14 | endif()
15 | include( ${HELPERS_PATH}/Helpers.cmake ) # Cross-Platform functions
16 |
17 | #####################################################################################
18 | # Sample requirements
19 |
20 | set ( REQUIRE_JPG "0" )
21 | set ( REQUIRE_PNG "0" )
22 | set ( REQUIRE_TGA "0" )
23 | set ( REQUIRE_VEC "1" )
24 | set ( REQUIRE_CAM "1" )
25 | set ( REQUIRE_GLEW "1" )
26 | set ( REQUIRE_DIRECTORY "0" )
27 | set ( REQUIRE_STRHELPER "0" )
28 | set ( REQUIRE_MAIN "1" )
29 | set ( REQUIRE_NVGUI "1" )
30 |
31 | # add_definitions(-DBUILD_BMP)
32 |
33 |
34 | ####################################################################################
35 | # Find Sample Utils
36 | #
37 | find_package(Utils)
38 |
39 | #####################################################################################
40 | # Require OpenGL
41 | #
42 | IF(WIN32)
43 | LIST(APPEND LIBRARIES_OPTIMIZED "opengl32.lib" )
44 | LIST(APPEND LIBRARIES_DEBUG "opengl32.lib" )
45 | ENDIF()
46 |
47 | #####################################################################################
48 | # Source files for this project
49 | #
50 | file(GLOB SOURCE_FILES *.cpp *.c *.h )
51 |
52 |
53 | ########################################################################3
54 | # Collect shaders for reference
55 | file(GLOB GLSL_FILES ${ASSET_PATH}/*.glsl )
56 |
57 | #####################################################################################
58 | # Executable
59 | #
60 | unset ( ALL_SOURCE_FILES )
61 | list( APPEND ALL_SOURCE_FILES ${SOURCE_FILES} )
62 | list( APPEND ALL_SOURCE_FILES ${COMMON_SOURCE_FILES} )
63 | list( APPEND ALL_SOURCE_FILES ${PACKAGE_SOURCE_FILES} )
64 | list( APPEND ALL_SOURCE_FILES ${UTIL_SOURCE_FILES} )
65 | list( APPEND ALL_SOURCE_FILES ${CUDA_FILES} )
66 |
67 | if ( NOT DEFINED WIN32 )
68 | #find_library(NVTOOLSEXT nvToolsExt HINTS ${CUDA_TOOLKIT_ROOT_DIR}/lib64)
69 | #set(libdeps GL GLEW X11 ${NVTOOLSEXT})
70 | set(libdeps GL GLEW X11 )
71 | LIST(APPEND LIBRARIES_OPTIMIZED ${libdeps})
72 | LIST(APPEND LIBRARIES_DEBUG ${libdeps})
73 | ENDIF()
74 |
75 | include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")
76 | add_definitions(-DGVDB_IMPORTS -DGLEW_STATIC -DGLEW_NO_GLU)
77 | add_definitions(-DASSET_PATH="${ASSET_PATH}/")
78 | add_executable (${PROJNAME} ${ALL_SOURCE_FILES} ${CUDA_FILES} ${PTX_SOURCES} ${GLSL_FILES} )
79 | set_property ( TARGET ${PROJNAME} APPEND PROPERTY DEPENDS ${PTX_SOURCES} )
80 |
81 |
82 | if ( MSVC )
83 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} )
84 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH} )
85 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH} )
86 | source_group(CUDA FILES ${CUDA_FILES})
87 | source_group(PTX FILES ${PTX_FILES})
88 | source_group(Helpers FILES ${UTIL_SOURCE_FILES})
89 |
90 | source_group(Core FILES ${SOURCE_FILES})
91 | endif ()
92 |
93 |
94 |
95 | #####################################################################################
96 | # Library dependencies
97 | #
98 | set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS Debug)
99 |
100 | foreach (loop_var IN ITEMS ${LIBRARIES_OPTIMIZED} )
101 | target_link_libraries ( ${PROJNAME} optimized ${loop_var} )
102 | endforeach()
103 |
104 | foreach (loop_var IN ITEMS ${LIBRARIES_DEBUG} )
105 | target_link_libraries ( ${PROJNAME} debug ${loop_var} )
106 | endforeach()
107 |
108 | message ( STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}" )
109 | message ( STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}" )
110 | message ( STATUS "EXECUTABLE_OUTPUT_PATH: ${EXECUTABLE_OUTPUT_PATH}" )
111 |
112 |
113 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | InvK - Inverse Kinematics Library using Quaternions
4 | ------------------------------------------------
5 |
6 | by Rama Hoetzlein ([ramakarl.com](http://ramakarl.com))
7 |
8 | This is a simple library that demonsrates an efficient solution to
9 | inverse kinematic chains using the Jacobian Transpose method over
10 | quaternions. The goal of this library is to enable a baseline
11 | implementation with few dependencies upon which to build larger projects.
12 |
13 | **Video demo here**:
14 | [Youtube link](https://youtu.be/j6bwD-kF_BI)
15 |
16 | **Citations**:
17 | You can cite this work as follows:
18 | Hoetzlein, Rama. "INVK - A lightweight Inverse Kinematics Library using Quaternions", May 6th, 2019. Online at: github.com/ramakarl/invk
19 |
20 | More useful reading material:
21 |
22 | Steve Rotenberg, Inverse Kinematics (part 1), UCSB. [Slides](https://cseweb.ucsd.edu/classes/wi17/cse169-a/slides/CSE169_08.pdf)
23 | Steve Rotenberg, Inverse Kinematics (part 2), UCSB. [Slides](https://cseweb.ucsd.edu/classes/wi17/cse169-a/slides/CSE169_09.pdf)
24 | Andreas Aristidou and Joan Lasenby, Inverse Kinematics: a review of existing techniques and introduction of a new fast iterative solver. [Tech Report](http://www.andreasaristidou.com/publications/papers/CUEDF-INFENG,%20TR-632.pdf)
25 |
26 | IK and Quaternions
27 | ------------------
28 | Quaternions allow for several benefits over Euler angles. First, axis boundaries are greatly simplified as quaternions can interpolate thru two arbitrary vectors. Second, IK requires incremental changes in angles which are well suited to quaternions. Third, quaternions are more efficient to compute for certain operations.
29 |
30 | There are two drawbacks to using quaternions for inverse kinematics. Per-axis angle range limits are more easily computed with Euler angles, so there is a conversion performed in the LimitQuaternion function to handle this. Finally, care must be taken to normalize the quaternions frequently during calculations.
31 |
32 | Quaternions can represent an orientation (a local coordinate system), or they can represent a rotation (amount to rotate around a given axis), which makes it easy to compute changes in orientation. For example, a key operation during IK is to rotate a joint around its local coordinate X,Y or Z axis by an incremental angle. This is easily accomplished by observing that a joint which is oriented by a quaternion is **locally** rotated by performed a post-multiplying with a rotational quaternion.
33 |
34 | P.fromAngleAxis ( angle, Vector3DF(0, 1, 0) ); // where angle is a scalar, vec<0,1,0> = Y-axis
35 | Q = Q * P; // post-multiply to perform a rotation around the **local** Y-axis of Q.
36 | Q = P * Q; // pre-multiply to perform a rotation around the **global** Y-axis of Q.
37 |
38 | Where Q is a quaternion for local orientation, and P is a rotational quaternion. Notice the output Q is not a point but another quaternion (a new orientation).
39 |
40 | Revision History
41 | --------
42 | May 6, 2019 - v1.0 - Support for hinge and ball joints, with joint limits.
43 |
44 | How to Build
45 | -------
46 | * You will need to install cmake
47 | 1. Clone into a folder for invk
48 | 2. Create a build folder somewhere, eg. invk/build
49 | 3. From inside that folder: invk/build> cmake .. -DCMAKE_HELPERS_PATH=invk/helpers
50 | 4. When compile & generate succeed, run 'make'
51 |
52 | LICENSE
53 | -------
54 | This library is licensed under the LGPLv3 license.
55 | https://www.gnu.org/licenses/lgpl-3.0.txt
56 |
57 | Short summary:
58 | - Public changes to the library itself must be back-contributed or forked as LGPL
59 | - Use in larger projects that are not LGPL are allowed
60 |
61 | Rama Hoetzlein (c) May 2019
62 |
--------------------------------------------------------------------------------
/helpers/FindUtils.cmake:
--------------------------------------------------------------------------------
1 |
2 |
3 | #####################################################################################
4 | # Find Sample Utils
5 | #
6 | unset( UTILS_FOUND CACHE)
7 |
8 | message ( STATUS "--> Find Sample Utils")
9 |
10 | set ( SAMPLE_UTIL_DIR "${CMAKE_HELPERS_PATH}" CACHE PATH "Path to sample_utils" )
11 |
12 | set ( OK_UTIL "0" )
13 | _FIND_FILE ( UTIL_FILES SAMPLE_UTIL_DIR "nv_gui.h" "nv_gui.h" OK_UTIL )
14 |
15 | if ( OK_UTIL EQUAL 1 )
16 | set ( UTILS_FOUND "YES" )
17 | include_directories( ${SAMPLE_UTIL_DIR} )
18 |
19 | # OpenGL always required
20 | if ( REQUIRE_OPENGL )
21 | find_package(OpenGL)
22 | message ( STATUS " Using OpenGL")
23 | endif()
24 |
25 | #-------------------------------- Image formats
26 | if ( REQUIRE_PNG )
27 | # Add PNG to build
28 | message ( STATUS " Using PNG")
29 | add_definitions(-DBUILD_PNG)
30 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/file_png.cpp" )
31 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/file_png.h" )
32 | endif()
33 | if ( REQUIRE_TGA )
34 | # Add TGA to build
35 | message ( STATUS " Using TGA")
36 | add_definitions(-DBUILD_TGA)
37 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/file_tga.cpp" )
38 | endif()
39 | if ( REQUIRE_JPG )
40 | message( STATUS " Using JPG")
41 | add_definitions(-DBUILD_JPG)
42 | LIST(APPEND LIBRARIES_OPTIMIZED "${COMBINED_LIB_PATH}/libjpg_2015x64.lib" )
43 | LIST(APPEND LIBRARIES_DEBUG "${COMBINED_LIB_PATH}/libjpg_2015x64d.lib" )
44 | endif()
45 | #---------------------------------------- Graphics Libs
46 | if ( REQUIRE_OPTIX )
47 | # Add OptiX to build
48 | # Collect all OptiX utility files
49 | add_definitions(-DUSE_OPTIX_UTILS)
50 | message ( STATUS " Using OPTIX_UTILS")
51 | FILE( GLOB UTIL_OPTIX_FILES "${SAMPLE_UTIL_DIR}/optix*.cpp" "${SAMPLE_UTIL_DIR}/optix*.hpp")
52 | FILE( GLOB UTIL_OPTIX_KERNELS "${SAMPLE_UTIL_DIR}/optix*.cu" "${SAMPLE_UTIL_DIR}/optix*.cuh")
53 | endif()
54 | if ( REQUIRE_GLEW )
55 | # Add GLEW to build
56 | message ( STATUS " Using GLEW")
57 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/glew.c" )
58 | endif()
59 | if ( REQUIRE_NVGUI )
60 | # Add NVGUI to build
61 | message ( STATUS " Using NVGUI")
62 | add_definitions(-DUSE_NVGUI)
63 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/nv_gui.cpp" )
64 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/nv_gui.h" )
65 | endif()
66 | if ( REQUIRE_CAM )
67 | # Add Camera to build
68 | message ( STATUS " Using CAM")
69 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/camera.cpp" )
70 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/camera.h" )
71 | endif()
72 | if ( REQUIRE_VEC )
73 | # Add Vec to build
74 | message ( STATUS " Using VEC")
75 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/vec.cpp" )
76 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/vec.h" )
77 | endif()
78 | #---------------------------------------- Strings & Dirs
79 | if ( REQUIRE_STRHELPER )
80 | message ( STATUS " Using STR_HELPER")
81 | add_definitions(-DUSE_STR_HELPER)
82 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/string_helper.cpp" )
83 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/string_helper.h" )
84 | endif()
85 | if ( REQUIRE_DIRECTORY )
86 | message ( STATUS " Using DIRECTORY")
87 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/directory.cpp" )
88 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/directory.h" )
89 | endif()
90 | #---------------------------------------- Main
91 | if ( REQUIRE_MAIN )
92 | # Add Main to build
93 | IF(WIN32)
94 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/main_win.cpp" )
95 | ELSE()
96 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/main_x11.cpp" )
97 | ENDIF()
98 | LIST( APPEND UTIL_SOURCE_FILES "${SAMPLE_UTIL_DIR}/main.h" )
99 | endif()
100 |
101 | message ( STATUS "--> Using Sample Utils. ${SAMPLE_UTIL_DIR}\n")
102 | else()
103 | set ( UTILS_FOUND "NO" )
104 | message ( FATAL_ERROR "
105 | Sample Utils not found. Please set the CMAKE_MODULE_PATH \
106 | and the SAMPLE_UTIL_DIR to the location of sample_utils path, \
107 | which contains nv_gui, file_png, file_tga, main_win, main_x11, \
108 | and cmake helpers. \n
109 | ")
110 | endif()
111 |
112 | mark_as_advanced( UTILS_FOUND )
113 |
--------------------------------------------------------------------------------
/helpers/Helpers.cmake:
--------------------------------------------------------------------------------
1 |
2 | ####################################################################################
3 | # CMAKE HELPERS - GLOBAL START
4 |
5 | # Helpers path
6 | set ( CMAKE_HELPERS_PATH ${HELPERS_PATH} CACHE PATH "Full path to helpers." )
7 | set ( CMAKE_MODULE_PATH ${CMAKE_HELPERS_PATH} CACHE PATH "Full path to cmake finders.")
8 | set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Executable path" )
9 |
10 | # Asset path
11 | if ( NOT DEFINED ASSET_PATH )
12 | get_filename_component ( _assets "${BASE_DIRECTORY}/assets" REALPATH )
13 | set ( ASSET_PATH ${_assets} CACHE PATH "Full path to /assets" )
14 | endif()
15 |
16 | # Combined libraries
17 | get_filename_component ( _combined "${CMAKE_HELPERS_PATH}/../combined" REALPATH )
18 | set ( COMBINED_ROOT_DIR ${_combined} CACHE PATH "Path to combined libraries.")
19 | set ( COMBINED_LIB_PATH "${_combined}/lib/" CACHE PATH "Combined libs.")
20 | set ( COMBINED_INCLUDE_PATH "${_combined}/include/" CACHE PATH "Combined includes.")
21 | include_directories( ${COMBINED_INCLUDE_PATH} )
22 |
23 | set ( DEBUG_HEAP false CACHE BOOL "Enable heap checking (debug or release).")
24 | if ( ${DEBUG_HEAP} )
25 | add_definitions( -DDEBUG_HEAP)
26 | add_definitions( -D_CRTDBG_MAP_ALLOC)
27 | endif()
28 |
29 | message ( "-------- HELPER BOOTSTRAP ----------------" )
30 | message ( "BASE DIRECTORY: ${BASE_DIRECTORY}" )
31 | message ( "ASSET_PATH: ${ASSET_PATH}" )
32 | message ( "CMAKE_HELPERS_PATH: ${CMAKE_HELPERS_PATH}" )
33 | message ( "COMBINED_ROOT_DIR: ${COMBINED_ROOT_DIR}" )
34 | message ( "COMBINED_LIB_PATH: ${COMBINED_LIB_PATH}" )
35 | message ( "COMBINED_INC_PATH: ${COMBINED_INCLUDE_PATH}" )
36 |
37 |
38 | #-------------------------------------- COPY CUDA BINS
39 | # This macro copies all binaries for the CUDA library to the target executale location.
40 | #
41 | macro(_copy_cuda_bins projname )
42 | add_custom_command(
43 | TARGET ${projname} POST_BUILD
44 | COMMAND ${CMAKE_COMMAND} -E copy ${CUDA_DLL} $
45 | )
46 | endmacro()
47 |
48 |
49 | #------------------------------------ CROSS-PLATFORM PTX COMPILE
50 | #
51 | # _COMPILEPTX( SOURCES file1.cu file2.cu TARGET_PATH GENERATED_FILES ptx_sources NVCC_OPTIONS -arch=sm_20)
52 | # Generates ptx files for the given source files. ptx_sources will contain the list of generated files.
53 | #
54 | FUNCTION( _COMPILEPTX )
55 | set(options "")
56 | set(oneValueArgs TARGET_PATH GENERATED GENPATHS INCLUDE)
57 | set(multiValueArgs OPTIONS SOURCES)
58 | CMAKE_PARSE_ARGUMENTS( _COMPILEPTX "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
59 |
60 | # Match the bitness of the ptx to the bitness of the application
61 | set( MACHINE "--machine=32" )
62 | if( CMAKE_SIZEOF_VOID_P EQUAL 8)
63 | set( MACHINE "--machine=64" )
64 | endif()
65 | unset ( PTX_FILES CACHE )
66 | unset ( PTX_FILES_PATH CACHE )
67 |
68 | set( USE_DEBUG_PTX OFF CACHE BOOL "Enable CUDA debugging with NSight")
69 | if ( USE_DEBUG_PTX )
70 | set ( DEBUG_FLAGS ";-g;-G;-D_DEBUG;-DEBUG")
71 | else()
72 | set ( DEBUG_FLAGS "")
73 | endif()
74 |
75 | if ( WIN32 )
76 | # Windows - PTX compile
77 | file ( MAKE_DIRECTORY "${_COMPILEPTX_TARGET_PATH}/Debug" )
78 | file ( MAKE_DIRECTORY "${_COMPILEPTX_TARGET_PATH}/Release" )
79 | string (REPLACE ";" " " _COMPILEPTX_OPTIONS "${_COMPILEPTX_OPTIONS}")
80 | separate_arguments( _OPTS WINDOWS_COMMAND "${_COMPILEPTX_OPTIONS}" )
81 | message ( STATUS "NVCC Options: ${_COMPILEPTX_OPTIONS}" )
82 | message ( STATUS "NVCC Include: ${_COMPILEPTX_INCLUDE}" )
83 |
84 | set ( INCL "-I\"${_COMPILEPTX_INCLUDE}\"" )
85 |
86 | # Custom build rule to generate ptx files from cuda files
87 | FOREACH( input ${_COMPILEPTX_SOURCES} )
88 | get_filename_component( input_ext ${input} EXT ) # Input extension
89 | get_filename_component( input_without_ext ${input} NAME_WE ) # Input base
90 | if ( ${input_ext} STREQUAL ".cu" )
91 |
92 | # Set output names
93 | set( output "${input_without_ext}.ptx" ) # Output name
94 | set( output_with_path "${_COMPILEPTX_TARGET_PATH}/$(Configuration)/${input_without_ext}.ptx" ) # Output with path
95 | set( output_with_quote "\"${output_with_path}\"" )
96 | LIST( APPEND PTX_FILES ${output} ) # Append to output list
97 | LIST( APPEND PTX_FILES_PATH ${output_with_path} )
98 |
99 | message( STATUS "NVCC Compile: ${CUDA_NVCC_EXECUTABLE} ${MACHINE} --ptx ${_COMPILEPTX_OPTIONS} ${input} ${INCL} -o ${output_with_path} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}")
100 |
101 | add_custom_command(
102 | OUTPUT ${output_with_path}
103 | MAIN_DEPENDENCY ${input}
104 | COMMAND ${CUDA_NVCC_EXECUTABLE} ${MACHINE} --ptx ${_OPTS} ${input} ${INCL} -o ${output_with_quote} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
105 | )
106 | endif()
107 | ENDFOREACH( )
108 | else ()
109 | # Linux - PTX compile
110 | file ( MAKE_DIRECTORY "${_COMPILEPTX_TARGET_PATH}" )
111 | cuda_compile_ptx(PTX_FILES ${_COMPILEPTX_SOURCES} )
112 | SET ( PTX_FILES_PATH ${PTX_FILES} )
113 | endif()
114 |
115 | set( ${_COMPILEPTX_GENERATED} ${PTX_FILES} PARENT_SCOPE)
116 | set( ${_COMPILEPTX_GENPATHS} ${PTX_FILES_PATH} PARENT_SCOPE)
117 |
118 | ENDFUNCTION()
119 |
120 | #------------------------------------ CROSS-PLATFORM INSTALL
121 | function( _INSTALL )
122 | set (options "")
123 | set (oneValueArgs DESTINATION SOURCE OUTPUT )
124 | set (multiValueArgs FILES )
125 | CMAKE_PARSE_ARGUMENTS(_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
126 | if ( _INSTALL_SOURCE )
127 | set ( _INSTALL_SOURCE "${_INSTALL_SOURCE}/" )
128 | endif()
129 | set ( OUT_LIST ${${_INSTALL_OUTPUT}} )
130 |
131 | if ( WIN32 )
132 | # Windows - copy to desintation at post-build
133 | file ( MAKE_DIRECTORY "${_INSTALL_DESTINATION}/" )
134 | foreach (_file ${_INSTALL_FILES} )
135 | message ( STATUS "Install: ${_INSTALL_SOURCE}${_file} -> ${_INSTALL_DESTINATION}" )
136 | add_custom_command(
137 | TARGET ${PROJNAME} POST_BUILD
138 | COMMAND ${CMAKE_COMMAND} -E copy ${_INSTALL_SOURCE}${_file} ${_INSTALL_DESTINATION}
139 | )
140 | list ( APPEND OUT_LIST "${_INSTALL_SOURCE}${_file}" )
141 | endforeach()
142 | else ()
143 | # Linux
144 | if ( _INSTALL_SOURCE )
145 | foreach ( _file ${_INSTALL_FILES} )
146 | list ( APPEND OUT_LIST "${_INSTALL_SOURCE}${_file}" )
147 | endforeach()
148 | else()
149 | list ( APPEND OUT_LIST ${_INSTALL_FILES} )
150 | endif()
151 | endif( )
152 | set ( ${_INSTALL_OUTPUT} ${OUT_LIST} PARENT_SCOPE )
153 |
154 | endfunction()
155 |
156 | #------------------------------------------------- CROSS-PLATFORM INSTALL PTX
157 | #
158 | function( _INSTALL_PTX )
159 | set (options "")
160 | set (oneValueArgs DESTINATION OUTPUT )
161 | set (multiValueArgs FILES )
162 | CMAKE_PARSE_ARGUMENTS(_INSTALL_PTX "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
163 |
164 | set ( OUT_LIST ${${_INSTALL_PTX_OUTPUT}} )
165 |
166 | unset ( PTX_FIXED )
167 |
168 | if ( WIN32 )
169 |
170 | foreach ( _file IN ITEMS ${_INSTALL_PTX_FILES} )
171 | get_filename_component ( _ptxbase ${_file} NAME_WE )
172 | get_filename_component ( _ptxpath ${_file} DIRECTORY )
173 | get_filename_component ( _ptxparent ${_ptxpath} DIRECTORY ) # parent directory
174 | set ( _fixed "${_ptxparent}/${_ptxbase}.ptx" ) # copy to parent to remove compile time $(Configuration) path
175 | add_custom_command ( TARGET ${PROJNAME} POST_BUILD
176 | COMMAND ${CMAKE_COMMAND} -E copy ${_file} ${_fixed}
177 | )
178 | list ( APPEND PTX_FIXED ${_file} ) # NOTE: Input of FILES must be list of ptx *with paths*
179 | list ( APPEND OUT_LIST ${_fixed} )
180 | endforeach()
181 |
182 | else()
183 |
184 | foreach ( _file IN ITEMS ${_INSTALL_PTX_FILES} )
185 | get_filename_component ( _ptxpath ${_file} DIRECTORY )
186 | get_filename_component ( _ptxbase ${_file} NAME_WE )
187 | string ( SUBSTRING ${_ptxbase} 27 -1 _ptxname )
188 | set ( _fixed "${_ptxpath}/${_ptxname}.ptx" )
189 | add_custom_command ( TARGET ${PROJNAME} PRE_LINK
190 | COMMAND ${CMAKE_COMMAND} -E copy ${_file} ${_fixed}
191 | )
192 | list ( APPEND PTX_FIXED ${_fixed} )
193 | list ( APPEND OUT_LIST ${_fixed} )
194 | endforeach()
195 | endif()
196 |
197 | # Install PTX
198 | message ( STATUS "PTX files: ${PTX_FIXED}" )
199 | _INSTALL ( FILES ${PTX_FIXED} DESTINATION ${_INSTALL_PTX_DESTINATION} )
200 |
201 | set ( ${_INSTALL_PTX_OUTPUT} ${OUT_LIST} PARENT_SCOPE )
202 |
203 | endfunction()
204 |
205 |
206 | #----------------------------------------------- CROSS-PLATFORM FIND FILES
207 | # Find one or more of a specific file in the given folder
208 | # Returns the file name w/o path
209 |
210 | macro(_FIND_FILE targetVar searchDir nameWin64 nameLnx cnt)
211 | unset ( fileList )
212 | unset ( nameFind )
213 | unset ( targetVar )
214 | if ( WIN32 )
215 | SET ( nameFind ${nameWin64} )
216 | else()
217 | SET ( nameFind ${nameLnx} )
218 | endif()
219 | if ( "${nameFind}" STREQUAL "" )
220 | MATH (EXPR ${cnt} "${${cnt}}+1" )
221 | else()
222 | file(GLOB fileList "${${searchDir}}/${nameFind}")
223 | list(LENGTH fileList NUMLIST)
224 | if (NUMLIST GREATER 0)
225 | MATH (EXPR ${cnt} "${${cnt}}+1" )
226 | list(APPEND ${targetVar} ${nameFind} )
227 | endif()
228 | endif()
229 | endmacro()
230 |
231 | #----------------------------------------------- CROSS-PLATFORM FIND MULTIPLE
232 | # Find all files in specified folder with the given extension.
233 | # This creates a file list, where each entry is only the filename w/o path
234 | # Return the count of files
235 | macro(_FIND_MULTIPLE targetVar searchDir extWin64 extLnx cnt)
236 | unset ( fileList )
237 | unset ( targetVar )
238 | unset ( ${cnt} )
239 | set ( ${cnt} "0" )
240 | if ( WIN32 )
241 | SET ( extFind ${extWin64} )
242 | else()
243 | SET ( extFind ${extLnx} )
244 | endif()
245 | file( GLOB fileList "${${searchDir}}/*.${extFind}")
246 | list( LENGTH fileList NUMLIST)
247 | math( EXPR ${cnt} "${${cnt}}+${NUMLIST}" )
248 | foreach ( _file ${fileList} )
249 | get_filename_component ( fname ${_file} NAME )
250 | list( APPEND ${targetVar} ${fname} )
251 | endforeach()
252 | endmacro()
253 |
254 | #----------------------------------------------- LIST ALL source
255 | function(_LIST_ALL_SOURCE )
256 | set (options "")
257 | set (oneValueArgs "" )
258 | set (multiValueArgs FILES )
259 | CMAKE_PARSE_ARGUMENTS(_LIST_ALL_SOURCE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
260 |
261 | unset ( SOURCE_LIST )
262 | foreach ( _file IN ITEMS ${_LIST_ALL_SOURCE_FILES} )
263 | message ( STATUS "Source: ${_file}") # uncomment to check source files
264 | list ( APPEND SOURCE_LIST ${_file} )
265 | endforeach()
266 |
267 | set ( ALL_SOURCE_FILES ${SOURCE_LIST} PARENT_SCOPE )
268 | endfunction()
269 |
270 | function(_LINK )
271 | set (options "")
272 | set (multiValueArgs PROJECT OPT DEBUG PLATFORM )
273 | CMAKE_PARSE_ARGUMENTS(_LINK "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
274 |
275 | set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS Debug PARENT_SCOPE )
276 |
277 | set (PROJ_NAME ${_LINK_PROJECT})
278 |
279 | foreach (loop_var IN ITEMS ${_LINK_PLATFORM} )
280 | target_link_libraries( ${PROJ_NAME} general ${loop_var} )
281 | list (APPEND LIBLIST ${loop_var})
282 | endforeach()
283 |
284 | foreach (loop_var IN ITEMS ${_LINK_DEBUG} )
285 | target_link_libraries ( ${PROJ_NAME} debug ${loop_var} )
286 | list (APPEND LIBLIST ${loop_var})
287 | endforeach()
288 |
289 | foreach (loop_var IN ITEMS ${_LINK_OPT} )
290 | target_link_libraries ( ${PROJ_NAME} optimized ${loop_var} )
291 | endforeach()
292 |
293 | string (REPLACE ";" "\n " OUTSTR "${LIBLIST}")
294 | message ( STATUS "Libraries used:\n ${OUTSTR}" )
295 | endfunction()
296 |
297 | macro(_MSVC_PROPERTIES)
298 | # Instruct CMake to automatically build INSTALL project in Visual Studio
299 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
300 |
301 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} )
302 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH} )
303 | set_target_properties( ${PROJNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH} )
304 |
305 | # Set startup PROJECT
306 | if ( (${CMAKE_MAJOR_VERSION} EQUAL 3 AND ${CMAKE_MINOR_VERSION} GREATER 5) OR (${CMAKE_MAJOR_VERSION} GREATER 3) )
307 | message ( STATUS "VS Startup Project: ${CMAKE_CURRENT_BINARY_DIR}, ${PROJNAME}")
308 | set_property ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJNAME} )
309 | endif()
310 |
311 | # Source groups
312 | source_group(CUDA FILES ${CUDA_FILES})
313 | source_group(PTX FILES ${PTX_FILES})
314 | source_group(OPTIX FILES ${UTIL_OPTIX_KERNELS})
315 | endmacro ()
316 |
317 | macro(_DEFAULT_INSTALL_PATH)
318 | if ( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT )
319 | if (WIN32)
320 | get_filename_component ( _instpath "${CMAKE_CURRENT_SOURCE_DIR}/../../_output" REALPATH )
321 | else()
322 | get_filename_component ( _instpath "/usr/local/gvdb/_output" REALPATH )
323 | endif()
324 | set ( CMAKE_INSTALL_PREFIX ${_instpath} CACHE PATH "default install path" FORCE)
325 | endif()
326 | get_filename_component( BIN_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/bin REALPATH)
327 | endmacro()
328 |
--------------------------------------------------------------------------------
/helpers/Packages.cmake:
--------------------------------------------------------------------------------
1 |
2 | set(VERSION "1.3.3")
3 |
4 |
5 | if ( MSVC_VERSION )
6 | # MSVC_VERSION:
7 | # https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
8 | # 1600 - VS 11.0 - 2010
9 | # 1700 - VS 11.0 - 2012
10 | # 1800 - VS 12.0 - 2013
11 | # 1900 - VS 14.0 - 2015
12 | # 1910 - VS 14.1 - 2017
13 | # 1911 - VS 14.1 - 2017
14 | # 1912 - VS 15.0 - 2017
15 | message ( STATUS "MSVC_VERSION = ${MSVC_VERSION}" )
16 | if ( ${MSVC_VERSION} EQUAL "1600" )
17 | SET ( MSVC_YEAR "2010" )
18 | endif()
19 | if ( ${MSVC_VERSION} EQUAL "1700" )
20 | SET ( MSVC_YEAR "2012" )
21 | endif()
22 | if ( ${MSVC_VERSION} EQUAL "1800" )
23 | SET ( MSVC_YEAR "2013" )
24 | endif()
25 | if ( ${MSVC_VERSION} EQUAL "1900" )
26 | SET ( MSVC_YEAR "2015" )
27 | endif()
28 | if ( ${MSVC_VERSION} EQUAL "1910" )
29 | SET ( MSVC_YEAR "2017" )
30 | endif()
31 | if ( ${MSVC_VERSION} EQUAL "1911" )
32 | SET ( MSVC_YEAR "2017" )
33 | endif()
34 | if ( ${MSVC_VERSION} EQUAL "1912" )
35 | SET ( MSVC_YEAR "2017" ) # USE LIBS FOR VS2015 due to cl.exe issue
36 | endif()
37 | endif()
38 |
39 | # Set the default build to Release. Note this doesn't do anything for the VS
40 | # default build target.
41 | if(NOT CMAKE_BUILD_TYPE)
42 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING
43 | "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
44 | FORCE)
45 | endif(NOT CMAKE_BUILD_TYPE)
46 |
47 | #####################################################################################
48 | function(_make_relative FROM TO OUT)
49 | #message(STATUS "FROM = ${FROM}")
50 | #message(STATUS "TO = ${TO}")
51 |
52 | get_filename_component(FROM ${FROM} ABSOLUTE)
53 | get_filename_component(TO ${TO} ABSOLUTE)
54 |
55 | string(REPLACE "/" ";" FROM_LIST ${FROM})
56 | string(REPLACE "/" ";" TO_LIST ${TO})
57 |
58 | #message(STATUS "FROM = ${FROM_LIST}")
59 | #message(STATUS "TO = ${TO_LIST}")
60 |
61 | list(LENGTH FROM_LIST flen)
62 | math(EXPR flen "${flen} - 1" )
63 | #message(STATUS "flen = ${flen}")
64 | list(LENGTH TO_LIST tlen)
65 | math(EXPR tlen "${tlen} - 1" )
66 | #message(STATUS "tlen = ${tlen}")
67 |
68 | set(REL_LIST)
69 | foreach(loop_var RANGE ${flen})
70 | #message(STATUS "i = ${loop_var}")
71 | if ((loop_var GREATER tlen) OR (loop_var EQUAL tlen))
72 | list(APPEND REL_LIST "..")
73 | #message(STATUS "descend")
74 | else()
75 | list(GET FROM_LIST ${loop_var} f)
76 | list(GET TO_LIST ${loop_var} t)
77 | #message(STATUS "f = ${f}")
78 | #message(STATUS "t = ${t}")
79 | if (${f} STREQUAL ${t})
80 | set(begin ${loop_var})
81 | #message(STATUS "equal")
82 | else()
83 | list(APPEND REL_LIST "..")
84 | #message(STATUS "descend")
85 | endif()
86 | endif()
87 | endforeach(loop_var)
88 | if (begin)
89 | math(EXPR begin "${begin} + 1" )
90 | endif()
91 |
92 | #message(STATUS "---")
93 |
94 | foreach(loop_var RANGE ${begin} ${tlen})
95 | #message(STATUS "i = ${loop_var}")
96 | #message(STATUS "t = ${t}")
97 | #message(STATUS "ascend")
98 | list(GET TO_LIST ${loop_var} t)
99 | list(APPEND REL_LIST ${t})
100 | endforeach(loop_var)
101 |
102 | #message(STATUS "relative = ${REL_LIST}")
103 |
104 | string (REPLACE ";" "/" _TMP_STR "${REL_LIST}")
105 | set (${OUT} "${_TMP_STR}" PARENT_SCOPE)
106 | endfunction()
107 |
108 | macro(_add_project_definitions name)
109 | if(MSVC)
110 | _make_relative("${EXECUTABLE_OUTPUT_PATH}/config" "${CMAKE_CURRENT_SOURCE_DIR}" TOPROJECT)
111 | else()
112 | _make_relative("${EXECUTABLE_OUTPUT_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}" TOPROJECT)
113 | endif()
114 |
115 | #message(STATUS "${TOPROJECT}")
116 |
117 | add_definitions(-DPROJECT_RELDIRECTORY="${TOPROJECT}/")
118 | add_definitions(-DPROJECT_ABSDIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/")
119 | add_definitions(-DPROJECT_NAME="${name}")
120 |
121 | endmacro(_add_project_definitions)
122 |
123 | #####################################################################################
124 | if(UNIX)
125 | set(OS "linux")
126 | add_definitions(-DLINUX)
127 | else(UNIX)
128 | if(APPLE)
129 | else(APPLE)
130 | if(WIN32)
131 | set(OS "win")
132 | add_definitions(-DNOMINMAX)
133 | if(MEMORY_LEAKS_CHECK)
134 | add_definitions(-DMEMORY_LEAKS_CHECK)
135 | endif()
136 | endif(WIN32)
137 | endif(APPLE)
138 | endif(UNIX)
139 |
140 |
141 | if (MSVC90)
142 | include_directories(${BASE_DIRECTORY}/stdint_old_msvc)
143 | endif(MSVC90)
144 |
145 |
146 |
147 | #######################################################
148 | # LOCAL PACKAGES
149 | #
150 | macro ( _FIND_LOCALPACKAGE_CUDA )
151 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/CUDA)
152 | Message(STATUS "Local CUDA detected. Using it")
153 | set(CUDA_LOCALPACK_VER "9.0" CACHE STRING "CUDA Version")
154 | set(CUDA_TOOLKIT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/CUDA/v${CUDA_LOCALPACK_VER}_win")
155 | endif()
156 | endmacro()
157 |
158 | macro ( _FIND_LOCALPACKAGE_OPENVDB )
159 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/OpenVDB)
160 | Message(STATUS "Local OpenVDB detected. Using it")
161 | set(OPENVDB_LOCALPACK_VER "4.0.1" CACHE STRING "OpenVDB Version")
162 | set(OPENVDB_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/OpenVDB/OpenVDB_${OPENVDB_LOCALPACK_VER}_vs2015" )
163 | SET(USE_OPENVDB ON CACHE BOOL "Use OpenVDB" FORCE)
164 | endif()
165 | endmacro()
166 |
167 | macro ( _FIND_LOCALPACKAGE_OPTIX )
168 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/Optix)
169 | Message(STATUS "Local Optix detected. Using it")
170 | set(OPTIX_LOCALPACK_VER "5.0.0" CACHE STRING "OptiX Version")
171 | set(OPTIX_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../LocalPackages/Optix/Optix_${OPTIX_LOCALPACK_VER}_win64")
172 | endif()
173 | endmacro ()
174 |
175 | #####################################################################################
176 | # Optional GVDB
177 | #
178 | macro(_add_package_GVDB)
179 |
180 | message( STATUS "<-- Searching for package GVDB")
181 | find_package(GVDB)
182 |
183 | if ( GVDB_FOUND )
184 | message( STATUS "--> Using package GVDB. ${GVDB_LIB_DIR} ")
185 | include_directories( ${GVDB_INCLUDE_DIR} )
186 | add_definitions(-DUSE_GVDB)
187 | add_definitions(-DSIM_CODE)
188 | if (WIN32)
189 | LIST(APPEND LIBRARIES_OPTIMIZED ${GVDB_LIB_DIR}/${GVDB_LIB} )
190 | LIST(APPEND LIBRARIES_DEBUG ${GVDB_LIB_DIR}/${GVDB_LIB} )
191 | else ()
192 | find_library( LIBGVDB gvdb HINTS ${GVDB_LIB_DIR} )
193 | LIST(APPEND LIBRARIES_OPTIMIZED ${LIBGVDB} )
194 | LIST(APPEND LIBRARIES_DEBUG ${LIBGVDB} )
195 | endif()
196 | LIST(APPEND PACKAGE_SOURCE_FILES ${GVDB_INCLUDE_DIR}/${GVDB_HEADERS} )
197 | source_group(GVDB FILES ${GVDB_INCLUDE_DIR}/${GVDB_HEADERS} )
198 | else()
199 | message( FATAL_ERROR "--> Unable to find GVDB")
200 | endif()
201 |
202 | endmacro()
203 |
204 |
205 | #####################################################################################
206 | # Optional ZLIB
207 | #
208 | macro(_add_package_ZLIB)
209 | if(EXISTS ${BASE_DIRECTORY}/zlib)
210 | set(ZLIB_ROOT ${BASE_DIRECTORY}/zlib)
211 | endif()
212 | Message(STATUS "--> using package ZLIB")
213 | find_package(ZLIB)
214 | if(ZLIB_FOUND)
215 | include_directories(${ZLIB_INCLUDE_DIR})
216 | LIST(APPEND PACKAGE_SOURCE_FILES
217 | ${ZLIB_HEADERS}
218 | )
219 | LIST(APPEND LIBRARIES_OPTIMIZED ${ZLIB_LIBRARY})
220 | LIST(APPEND LIBRARIES_DEBUG ${ZLIB_LIBRARY})
221 | else()
222 | Message(WARNING "ZLIB not available. setting NOGZLIB define")
223 | add_definitions(-DNOGZLIB)
224 | endif()
225 | endmacro()
226 |
227 | #####################################################################################
228 | # Optional OpenVDB
229 | #
230 | macro(_add_package_OpenVDB)
231 |
232 | Message(STATUS "\n<-- Searching for OpenVDB")
233 |
234 | _FIND_LOCALPACKAGE_OPENVDB ()
235 |
236 | if ( NOT DEFINED USE_OPENVDB )
237 | SET(USE_OPENVDB OFF CACHE BOOL "Use OpenVDB")
238 | endif ()
239 |
240 | find_package(OpenVDB)
241 | if (OPENVDB_FOUND)
242 | if ( NOT DEFINED USE_OPENVDB )
243 | SET(USE_OPENVDB ON CACHE BOOL "Use OpenVDB")
244 | endif()
245 | if ( USE_OPENVDB )
246 | Message(STATUS "--> Using package OpenVDB")
247 |
248 | add_definitions(-DUSEOPENVDB)
249 | add_definitions(-DOPENEXR_DLL)
250 | add_definitions(-DOPENVDB_3_ABI_COMPATIBLE)
251 | add_definitions(-DBUILD_OPENVDB)
252 | add_definitions(-DOPENVDB_STATICLIB)
253 | add_definitions(-DOPENVDB_USE_BLOSC)
254 |
255 | message ( STATUS "Adding OpenVDB includes: ${OPENVDB_INCLUDE_DIR}" )
256 | include_directories(${OPENVDB_INCLUDE_DIR})
257 | include_directories ("${OPENVDB_INCLUDE_DIR}")
258 | include_directories ("${OPENVDB_INCLUDE_DIR}/IlmBase")
259 | include_directories ("${OPENVDB_INCLUDE_DIR}/tbb")
260 | LIST(APPEND LIBRARIES_OPTIMIZED ${OPENVDB_LIB_RELEASE} )
261 | LIST(APPEND LIBRARIES_DEBUG ${OPENVDB_LIB_DEBUG} )
262 |
263 | if ( OPENVDB_LIB_DIR STREQUAL "" )
264 | message ( FATAL_ERROR "OpenVDB package found, but OpenVDB library directory not found. OPENVDB_LIB_DIR." )
265 | endif ()
266 |
267 | if (MSVC_VERSION EQUAL 1600)
268 | set ( MSVCX "vc10" )
269 | endif()
270 | if (MSVC_VERSION EQUAL 1700)
271 | set ( MSVCX "vc11" )
272 | endif()
273 | if (MSVC_VERSION EQUAL 1800)
274 | set ( MSVCX "vc12" )
275 | endif()
276 | if (MSVC_VERSION EQUAL 1900)
277 | set ( MSVCX "vc14" )
278 | endif()
279 |
280 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/Blosc.lib" )
281 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/Blosc.lib" )
282 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/Half.lib" )
283 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/Half.lib" )
284 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/zlib.lib" )
285 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/zlibd.lib" )
286 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/tbb.lib" )
287 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/tbb_debug.lib" )
288 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/boost_system-${MSVCX}0-mt-1_64.lib" )
289 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/boost_system-${MSVCX}0-mt-gd-1_64.lib" )
290 | LIST(APPEND LIBRARIES_OPTIMIZED "${OPENVDB_LIB_DIR}/boost_thread-${MSVCX}0-mt-1_64.lib" )
291 | LIST(APPEND LIBRARIES_DEBUG "${OPENVDB_LIB_DIR}/boost_thread-${MSVCX}0-mt-gd-1_64.lib" )
292 |
293 | LIST(APPEND PACKAGE_SOURCE_FILES ${OPENVDB_HEADERS} )
294 | endif ()
295 | else()
296 | SET(USE_OPENVDB OFF CACHE BOOL "Use OpenVDB" FORCE)
297 | endif()
298 | endmacro()
299 |
300 |
301 | #####################################################################################
302 | # Optional Utils package
303 | #
304 | macro(_add_package_Utils)
305 |
306 | find_package(Utils)
307 |
308 | if ( UTILS_FOUND )
309 |
310 | if (WIN32)
311 | # Windows platform
312 | if(REQUIRE_OPENGL)
313 | add_definitions(-DBUILD_OPENGL)
314 | set(PLATFORM_LIBRARIES ${OPENGL_LIBRARY} )
315 | endif()
316 | else()
317 | # Linux platform
318 | if(REQUIRE_OPENGL)
319 | add_definitions(-DBUILD_OPENGL)
320 | set(PLATFORM_LIBRARIES GL GLU GLEW X11)
321 | endif()
322 | if(USE_NVTX)
323 | find_library(LIBNVTX nvToolsExt HINTS ${CUDA_TOOLKIT_ROOT_DIR}/lib64)
324 | LIST(APPEND LIBRARIES_OPTIMIZED ${LIBNVTX})
325 | LIST(APPEND LIBRARIES_DEBUG {LIBNVTX})
326 | endif()
327 | endif()
328 | endif()
329 |
330 | endmacro()
331 |
332 | #####################################################################################
333 | # Optional CUDA package
334 | #
335 |
336 | macro(_set_cuda_suffix)
337 | #------ CUDA VERSION
338 | if ( CUDA_VERSION )
339 | if ( ${CUDA_VERSION} EQUAL "8.0" )
340 | SET ( CUDA_SUFFIX "cu8" )
341 | endif ()
342 | if ( ${CUDA_VERSION} EQUAL "9.0" )
343 | SET ( CUDA_SUFFIX "cu9" )
344 | endif ()
345 | if ( ${CUDA_VERSION} EQUAL "9.1" )
346 | SET ( CUDA_SUFFIX "cu9" )
347 | endif ()
348 | else()
349 | message ( FATAL_ERROR "\nNVIDIA CUDA not found.\n" )
350 | endif()
351 | endmacro()
352 |
353 | macro(_add_package_CUDA)
354 |
355 | Message(STATUS "\n<-- Searching for CUDA")
356 |
357 | _FIND_LOCALPACKAGE_CUDA ()
358 |
359 | find_package(CUDA)
360 |
361 | if ( CUDA_FOUND )
362 | _set_cuda_suffix()
363 | message( STATUS "--> Using package CUDA (ver ${CUDA_VERSION})")
364 | add_definitions(-DUSECUDA)
365 | include_directories(${CUDA_TOOLKIT_INCLUDE})
366 | if (WIN32)
367 | LIST(APPEND LIBRARIES_OPTIMIZED ${CUDA_CUDA_LIBRARY} ${CUDA_CUDART_LIBRARY} )
368 | LIST(APPEND LIBRARIES_DEBUG ${CUDA_CUDA_LIBRARY} ${CUDA_CUDART_LIBRARY} )
369 | else()
370 | find_library(LIBCUDA cuda HINTS ${CUDA_TOOLKIT_ROOT_DIR}/lib64)
371 | find_library(LIBCUDART cudart HINTS ${CUDA_TOOLKIT_ROOT_DIR}/lib64)
372 | LIST(APPEND LIBRARIES_OPTIMIZED ${LIBCUDA})
373 | LIST(APPEND LIBRARIES_DEBUG ${LIBCUDART})
374 | endif()
375 | LIST(APPEND PACKAGE_SOURCE_FILES ${CUDA_TOOLKIT_INCLUDE} )
376 | source_group(CUDA FILES ${CUDA_TOOLKIT_INCLUDE} )
377 | else()
378 | message ( FATAL_ERROR "---> Unable to find package CUDA")
379 | endif()
380 |
381 | endmacro()
382 |
383 | #####################################################################################
384 | # Optional CUDPP package
385 | #
386 | macro(_add_package_CUDPP)
387 |
388 | Message(STATUS "\n<-- Searching for CUDPP")
389 |
390 | find_package(CUDPP)
391 |
392 | if (CUDPP_FOUND)
393 | if ( NOT DEFINED USE_CUDPP )
394 | SET(USE_CUDPP ON CACHE BOOL "Use CUDPP")
395 | endif()
396 | if ( USE_CUDPP )
397 | Message(STATUS "--> Using package CUDPP")
398 | add_definitions(-DUSE_CUDPP)
399 | include_directories( ${CUDPP_INCLUDE_DIR} )
400 | link_directories( ${CUDPP_LIB_DIR} )
401 | if (WIN32)
402 | LIST(APPEND LIBRARIES_OPTIMIZED ${CUDPP_LIB1_REL} )
403 | LIST(APPEND LIBRARIES_OPTIMIZED ${CUDPP_LIB2_REL} )
404 | LIST(APPEND LIBRARIES_DEBUG ${CUDPP_LIB1_DEBUG} )
405 | LIST(APPEND LIBRARIES_DEBUG ${CUDPP_LIB2_DEBUG} )
406 | else()
407 | find_library(LIBCUDPP cudpp HINTS ${GVDB_LIB_DIR} )
408 | find_library(LIBCUDPP_HASH cudpp_hash HINTS ${GVDB_LIB_DIR} )
409 | LIST(APPEND LIBRARIES_OPTIMIZED ${LIBCUDPP} ${LIBCUDPP_HASH} )
410 | LIST(APPEND LIBRARIES_DEBUG ${LIBCUDPP} ${LIBCUDPP_HASH} )
411 | endif()
412 | LIST(APPEND PACKAGE_SOURCE_FILES ${CUDPP_INCLUDE_DIR}/${CUDPP_HEADERS} )
413 | else()
414 | Message(FATAL_ERROR "--> NOT USING package CUDPP. Set USE_CUDPP true.")
415 | endif ()
416 | else ()
417 | SET(USE_CUDPP OFF CACHE BOOL "Use CUDPP")
418 | endif()
419 |
420 | endmacro()
421 |
422 | #####################################################################################
423 | # Optional OptiX package
424 | #
425 | macro(_add_package_Optix)
426 |
427 | Message(STATUS "<-- Searching for package OptiX")
428 |
429 | _FIND_LOCALPACKAGE_OPTIX()
430 |
431 | find_package(Optix)
432 |
433 | if (OPTIX_FOUND)
434 | if ( NOT DEFINED USE_OPTIX )
435 | SET(USE_OPTIX ON CACHE BOOL "Use OPTIX")
436 | endif()
437 | if ( USE_OPTIX )
438 | add_definitions(-DUSE_OPTIX)
439 | add_definitions(-DBUILD_OPTIX)
440 | include_directories(${OPTIX_INCLUDE_DIR})
441 | if (WIN32)
442 | LIST(APPEND LIBRARIES_OPTIMIZED ${OPTIX_LIB_DIR}/${OPTIX_LIB1} )
443 | LIST(APPEND LIBRARIES_OPTIMIZED ${OPTIX_LIB_DIR}/${OPTIX_LIB2} )
444 | LIST(APPEND LIBRARIES_DEBUG ${OPTIX_LIB_DIR}/${OPTIX_LIB1} )
445 | LIST(APPEND LIBRARIES_DEBUG ${OPTIX_LIB_DIR}/${OPTIX_LIB2} )
446 | else()
447 | find_library(LIBOPTIX optix HINTS ${OPTIX_LIB_DIR})
448 | find_library(LIBOPTIXU optixu HINTS ${OPTIX_LIB_DIR})
449 | LIST(APPEND LIBRARIES_OPTIMIZED ${LIBOPTIX} ${LIBOPTIXU} )
450 | LIST(APPEND LIBRARIES_DEBUG ${LIBOPTIX} ${LIBOPTIXU} )
451 | endif()
452 | LIST(APPEND PACKAGE_SOURCE_FILES ${OPTIX_INCLUDE_DIR}/${OPTIX_HEADERS} )
453 |
454 | _COMPILEPTX ( SOURCES ${UTIL_OPTIX_KERNELS} TARGET_PATH ${EXECUTABLE_OUTPUT_PATH} GENERATED UTIL_OPTIX_PTX GENPATHS UTIL_OPTIX_PTX_PATHS INCLUDE "${OPTIX_ROOT_DIR}/include/,${GVDB_INCLUDE_DIR},${CMAKE_CURRENT_SOURCE_DIR}" OPTIONS -arch=compute_30 -code=sm_30 --ptxas-options=-v -O3 --use_fast_math --maxrregcount=128 )
455 | message (STATUS " OptiX FILES: ${UTIL_OPTIX_FILES}")
456 | message (STATUS " OptiX KERNELS: ${UTIL_OPTIX_KERNELS}")
457 | message (STATUS " OptiX PTX: ${UTIL_OPTIX_PTX}")
458 | Message(STATUS "--> Using package OptiX\n")
459 |
460 | endif()
461 | else()
462 | Message(STATUS "Warning: OptiX not found. The gInteractiveOptix sample will not work without OptiX.")
463 | SET(USE_OPTIX OFF CACHE BOOL "Use Optix" FORCE)
464 | endif()
465 | endmacro()
466 |
467 | #####################################################################################
468 | #
469 | #
470 | set(TINYTHREADPP_DIRECTORY ${BASE_DIRECTORY}/tinythreadpp)
471 |
472 | macro(_add_package_tinythreadpp)
473 | Message(STATUS "--> using package TinyThread++")
474 | include_directories(${TINYTHREADPP_DIRECTORY}/src)
475 | set(PROJECT_TINYTHREADPP ${TINYTHREADPP_DIRECTORY}/src/fast_mutex.h ${TINYTHREADPP_DIRECTORY}/src/tinythread.h ${TINYTHREADPP_DIRECTORY}/src/tinythread.cpp)
476 |
477 | LIST(APPEND PACKAGE_SOURCE_FILES
478 | ${PROJECT_TINYTHREADPP}
479 | )
480 | endmacro(_add_package_tinythreadpp)
481 |
482 | #####################################################################################
483 | # Glew : source or lib
484 | if(GLEW_SOURCE)
485 | message(STATUS "found Glew source code. Using it instead of library")
486 | add_definitions(-DGLEW_STATIC)
487 | else()
488 | message(STATUS "using GLEW library")
489 | LIST(APPEND PLATFORM_LIBRARIES ${GLEW_LIBRARY})
490 | endif()
491 | add_definitions(-DGLEW_NO_GLU)
492 |
493 | ####################################################################################
494 | # XF86
495 | if (UNIX)
496 | LIST(APPEND PLATFORM_LIBRARIES "Xxf86vm")
497 | endif()
498 |
499 | #####################################################################################
500 | # NSight
501 | #
502 | # still need the include directory when no use of NSIGHT: for empty #defines
503 | macro(_add_package_NSight)
504 | Message(STATUS "--> using package NSight")
505 | include_directories(
506 | ${BASE_DIRECTORY}/NSight
507 | )
508 | if(SUPPORT_NVTOOLSEXT)
509 | link_directories(
510 | ${BASE_DIRECTORY}/NSight
511 | )
512 | LIST(APPEND PACKAGE_SOURCE_FILES
513 | ${BASE_DIRECTORY}/NSight/NSightEvents.h
514 | ${BASE_DIRECTORY}/NSight/nvToolsExt.h
515 | )
516 | add_definitions(-DSUPPORT_NVTOOLSEXT)
517 | if(ARCH STREQUAL "x86")
518 | SET(NSIGHT_DLL ${BASE_DIRECTORY}/NSight/nvToolsExt32_1.dll)
519 | SET(NSIGHT_LIB ${BASE_DIRECTORY}/NSight/nvToolsExt32_1.lib)
520 | else()
521 | SET(NSIGHT_DLL ${BASE_DIRECTORY}/NSight/nvToolsExt64_1.dll)
522 | SET(NSIGHT_LIB ${BASE_DIRECTORY}/NSight/nvToolsExt64_1.lib)
523 | endif()
524 | LIST(APPEND LIBRARIES_OPTIMIZED ${NSIGHT_LIB})
525 | LIST(APPEND LIBRARIES_DEBUG ${NSIGHT_LIB})
526 | endif()
527 | endmacro()
528 |
529 | ## -- no shared_sources to include (-Rama)
530 | # include_directories(
531 | # ${BASE_DIRECTORY}/shared_sources
532 | # )
533 |
534 | #####################################################################################
535 | # Macro to download a file from a URL
536 | #
537 | macro(_download_file _URL _TARGET _FORCE)
538 | if(${_FORCE} OR (NOT EXISTS ${_TARGET}))
539 | Message(STATUS "downloading ${_URL} ==> ${_TARGET}")
540 | file(DOWNLOAD ${_URL} ${_TARGET} SHOW_PROGRESS)
541 | else()
542 | Message(STATUS "model ${_TARGET} already loaded...")
543 | endif()
544 | endmacro()
545 | #
546 | # example: _download_files("${FILELIST}" "http://..." "${BASE_DIRECTORY}/shared_external/..." ${MODELS_DOWNLOAD_FORCE} )
547 | #
548 | macro(_download_files _FILELIST _URL _TARGET _FORCE )
549 | foreach(_FILE ${_FILELIST})
550 | if(${_FORCE} OR (NOT EXISTS "${_TARGET}/${_FILE}"))
551 | Message(STATUS "*******************************************")
552 | Message(STATUS "downloading ${_URL}/${_FILE}\n ==>\n ${_TARGET}")
553 | Message(STATUS "*******************************************")
554 | file(DOWNLOAD ${_URL}/${_FILE} ${_TARGET}/${_FILE} SHOW_PROGRESS)
555 | else()
556 | Message(STATUS "model ${_FILE} already loaded...")
557 | endif()
558 | endforeach(_FILE)
559 | endmacro()
560 |
--------------------------------------------------------------------------------
/helpers/camera.cpp:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------------------------------
2 | // NVIDIA(R) GVDB VOXELS
3 | // Copyright 2017, NVIDIA Corporation.
4 | //
5 | // Redistribution and use in source and binary forms, with or without modification,
6 | // are permitted provided that the following conditions are met:
7 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
9 | // in the documentation and/or other materials provided with the distribution.
10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
11 | // from this software without specific prior written permission.
12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
13 | // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
14 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
16 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 | //
19 | // Version 1.0: Rama Hoetzlein, 5/1/2017
20 | //----------------------------------------------------------------------------------
21 |
22 |
23 | #include "camera.h"
24 |
25 | // Camera3D IMPLEMENTATION
26 | //
27 | // The Camera3D transformation of an arbitrary point is:
28 | //
29 | // Q' = Q * T * R * P
30 | //
31 | // where Q = 3D point
32 | // Q' = Screen point
33 | // T = Camera3D Translation (moves Camera3D to origin)
34 | // R = Camera3D Rotation (rotates Camera3D to point 'up' along Z axis)
35 | // P = Projection (projects points onto XY plane)
36 | //
37 | // T is a unit-coordinate system translated to origin from Camera3D:
38 | // [1 0 0 0]
39 | // [0 1 0 0]
40 | // [0 0 1 0]
41 | // [-cx -cy -cz 0] where c is Camera3D location
42 | // R is a basis matrix:
43 | //
44 | // P is a projection matrix:
45 | //
46 |
47 | Camera3D::Camera3D ()
48 | {
49 |
50 | mProjType = Perspective;
51 | mWire = 0;
52 |
53 | up_dir.Set ( 0.0, 1.0, 0 ); // frustum params
54 | mAspect = (float) 800.0f/600.0f;
55 | mDolly = 5.0;
56 | mFov = 40.0;
57 | mNear = (float) 0.1;
58 | mFar = (float) 6000.0;
59 | mTile.Set ( 0, 0, 1, 1 );
60 |
61 | for (int n=0; n < 8; n++ ) mOps[n] = false;
62 | mOps[0] = false;
63 |
64 | // mOps[0] = true;
65 | // mOps[1] = true;
66 |
67 | setOrbit ( 0, 45, 0, Vector3DF(0,0,0), 120.0, 1.0 );
68 | updateMatricies ();
69 | }
70 |
71 | /*void Camera3D::draw_gl ()
72 | {
73 | Vector3DF pnt;
74 | int va, vb;
75 |
76 | if ( !mOps[0] ) return;
77 |
78 | // Box testing
79 | //
80 | // NOTES: This demonstrates AABB box testing against the frustum
81 | // Boxes tested are 10x10x10 size, spaced apart from each other so we can see them.
82 | if ( mOps[5] ) {
83 | glPushMatrix ();
84 | glEnable ( GL_LIGHTING );
85 | glColor3f ( 1, 1, 1 );
86 | Vector3DF bmin, bmax, vmin, vmax;
87 | int lod;
88 | for (float y=0; y < 100; y += 10.0 ) {
89 | for (float z=-100; z < 100; z += 10.0 ) {
90 | for (float x=-100; x < 100; x += 10.0 ) {
91 | bmin.Set ( x, y, z );
92 | bmax.Set ( x+8, y+8, z+8 );
93 | if ( boxInFrustum ( bmin, bmax ) ) {
94 | lod = (int) calculateLOD ( bmin, 1, 5, 300.0 );
95 | //rendGL->drawCube ( bmin, bmax, Vector3DF(1,1,1) );
96 | }
97 | }
98 | }
99 | }
100 | glPopMatrix ();
101 | }
102 |
103 | glDisable ( GL_LIGHTING );
104 | glLoadMatrixf ( getViewMatrix().GetDataF() );
105 |
106 | // Frustum planes (world space)
107 | //
108 | // NOTE: The frustum planes are drawn as discs because
109 | // they are boundless (infinite). The minimum information contained in the
110 | // plane equation is normal direction and distance from plane to origin.
111 | // This sufficiently defines infinite planes for inside/outside testing,
112 | // but cannot be used to draw the view frustum without more information.
113 | // Drawing is done as discs here to verify the frustum plane equations.
114 | if ( mOps[2] ) {
115 | glBegin ( GL_POINTS );
116 | glColor3f ( 1, 1, 0 );
117 | Vector3DF norm;
118 | Vector3DF side, up;
119 | for (int n=0; n < 6; n++ ) {
120 | norm.Set ( frustum[n][0], frustum[n][1], frustum[n][2] );
121 | glColor3f ( n/6.0, 1.0- (n/6.0), 0.5 );
122 | side = Vector3DF(0,1,0); side.Cross ( norm ); side.Normalize ();
123 | up = side; up.Cross ( norm ); up.Normalize();
124 | norm *= frustum[n][3];
125 | for (float y=-50; y < 50; y += 1.0 ) {
126 | for (float x=-50; x < 50; x += 1.0 ) {
127 | if ( x*x+y*y < 1000 ) {
128 | //pnt = side * x + up * y - norm;
129 | pnt = side;
130 | Vector3DF tv = up;
131 |
132 | tv *= y;
133 | pnt *= x;
134 | pnt += tv;
135 | pnt -= norm;
136 |
137 | glVertex3f ( pnt.x, pnt.y, pnt.z );
138 | }
139 | }
140 | }
141 | }
142 | glEnd ();
143 | }
144 |
145 | // Inside/outside testing
146 | //
147 | // NOTES: This code demonstrates frustum clipping
148 | // tests on individual points.
149 | if ( mOps[4] ) {
150 | glColor3f ( 1, 1, 1 );
151 | glBegin ( GL_POINTS );
152 | for (float z=-100; z < 100; z += 4.0 ) {
153 | for (float y=0; y < 100; y += 4.0 ) {
154 | for (float x=-100; x < 100; x += 4.0 ) {
155 | if ( pointInFrustum ( x, y, z) ) {
156 | glVertex3f ( x, y, z );
157 | }
158 | }
159 | }
160 | }
161 | glEnd ();
162 | }
163 |
164 | // Inverse rays (world space)
165 | //
166 | // NOTES: This code demonstrates drawing
167 | // inverse camera rays, as might be needed for raytracing or hit testing.
168 | if ( mOps[3] ) {
169 | glBegin ( GL_LINES );
170 | glColor3f ( 0, 1, 0);
171 | for (float x = 0; x <= 1.0; x+= 0.5 ) {
172 | for (float y = 0; y <= 1.0; y+= 0.5 ) {
173 | pnt = inverseRay ( x, y, mFar );
174 | pnt += from_pos;
175 | glVertex3f ( from_pos.x, from_pos.y, from_pos.z ); // all inverse rays originate at the camera center
176 | glVertex3f ( pnt.x, pnt.y, pnt.z );
177 | }
178 | }
179 | glEnd ();
180 | }
181 |
182 | // Projection
183 | //
184 | // NOTES: This code demonstrates
185 | // perspective projection _without_ using the OpenGL pipeline.
186 | // Projection is done by the camera class. A cube is drawn on the near plane.
187 |
188 | // Cube geometry
189 | Vector3DF pnts[8];
190 | Vector3DI edge[12];
191 | pnts[0].Set ( 0, 0, 0 ); pnts[1].Set ( 10, 0, 0 ); pnts[2].Set ( 10, 0, 10 ); pnts[3].Set ( 0, 0, 10 ); // lower points (y=0)
192 | pnts[4].Set ( 0, 10, 0 ); pnts[5].Set ( 10, 10, 0 ); pnts[6].Set ( 10, 10, 10 ); pnts[7].Set ( 0, 10, 10 ); // upper points (y=10)
193 | edge[0].Set ( 0, 1, 0 ); edge[1].Set ( 1, 2, 0 ); edge[2].Set ( 2, 3, 0 ); edge[3].Set ( 3, 0, 0 ); // 4 lower edges
194 | edge[4].Set ( 4, 5, 0 ); edge[5].Set ( 5, 6, 0 ); edge[6].Set ( 6, 7, 0 ); edge[7].Set ( 7, 4, 0 ); // 4 upper edges
195 | edge[8].Set ( 0, 4, 0 ); edge[9].Set ( 1, 5, 0 ); edge[10].Set ( 2, 6, 0 ); edge[11].Set ( 3, 7, 0 ); // 4 vertical edges
196 |
197 | // -- White cube is drawn using OpenGL projection
198 | if ( mOps[6] ) {
199 | glBegin ( GL_LINES );
200 | glColor3f ( 1, 1, 1);
201 | for (int e = 0; e < 12; e++ ) {
202 | va = edge[e].x;
203 | vb = edge[e].y;
204 | glVertex3f ( pnts[va].x, pnts[va].y, pnts[va].z );
205 | glVertex3f ( pnts[vb].x, pnts[vb].y, pnts[vb].z );
206 | }
207 | glEnd ();
208 | }
209 |
210 | //---- Draw the following in camera space..
211 | // NOTES:
212 | // The remainder drawing steps are done in
213 | // camera space. This is done by multiplying by the
214 | // inverse_rotation matrix, which transforms from camera to world space.
215 | // The camera axes, near, and far planes can now be drawn in camera space.
216 | glPushMatrix ();
217 | glLoadMatrixf ( getViewMatrix().GetDataF() );
218 | glTranslatef ( from_pos.x, from_pos.y, from_pos.z );
219 | glMultMatrixf ( invrot_matrix.GetDataF() ); // camera space --to--> world space
220 |
221 | // -- Red cube is drawn on the near plane using software projection pipeline. See Camera3D::project
222 | if ( mOps[6] ) {
223 | glBegin ( GL_LINES );
224 | glColor3f ( 1, 0, 0);
225 | Vector4DF proja, projb;
226 | for (int e = 0; e < 12; e++ ) {
227 | va = edge[e].x;
228 | vb = edge[e].y;
229 | proja = project ( pnts[va] );
230 | projb = project ( pnts[vb] );
231 | if ( proja.w > 0 && projb.w > 0 && proja.w < 1 && projb.w < 1) { // Very simple Z clipping (try commenting this out and see what happens)
232 | glVertex3f ( proja.x, proja.y, proja.z );
233 | glVertex3f ( projb.x, projb.y, projb.z );
234 | }
235 | }
236 | glEnd ();
237 | }
238 | // Camera axes
239 | glBegin ( GL_LINES );
240 | float to_d = (from_pos - to_pos).Length();
241 | glColor3f ( .8,.8,.8); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 0, -to_d );
242 | glColor3f ( 1,0,0); glVertex3f ( 0, 0, 0 ); glVertex3f ( 10, 0, 0 );
243 | glColor3f ( 0,1,0); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 10, 0 );
244 | glColor3f ( 0,0,1); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 0, 10 );
245 | glEnd ();
246 |
247 | if ( mOps[1] ) {
248 | // Near plane
249 | float sy = tan ( mFov * DEGtoRAD / 2.0);
250 | float sx = sy * mAspect;
251 | glColor3f ( 0.8, 0.8, 0.8 );
252 | glBegin ( GL_LINE_LOOP );
253 | glVertex3f ( -mNear*sx, mNear*sy, -mNear );
254 | glVertex3f ( mNear*sx, mNear*sy, -mNear );
255 | glVertex3f ( mNear*sx, -mNear*sy, -mNear );
256 | glVertex3f ( -mNear*sx, -mNear*sy, -mNear );
257 | glEnd ();
258 | // Far plane
259 | glBegin ( GL_LINE_LOOP );
260 | glVertex3f ( -mFar*sx, mFar*sy, -mFar );
261 | glVertex3f ( mFar*sx, mFar*sy, -mFar );
262 | glVertex3f ( mFar*sx, -mFar*sy, -mFar );
263 | glVertex3f ( -mFar*sx, -mFar*sy, -mFar );
264 | glEnd ();
265 |
266 | // Subview Near plane
267 | float l, r, t, b;
268 | l = -sx + 2.0*sx*mTile.x; // Tile is in range 0 <= x,y <= 1
269 | r = -sx + 2.0*sx*mTile.z;
270 | t = sy - 2.0*sy*mTile.y;
271 | b = sy - 2.0*sy*mTile.w;
272 | glColor3f ( 0.8, 0.8, 0.0 );
273 | glBegin ( GL_LINE_LOOP );
274 | glVertex3f ( l * mNear, t * mNear, -mNear );
275 | glVertex3f ( r * mNear, t * mNear, -mNear );
276 | glVertex3f ( r * mNear, b * mNear, -mNear );
277 | glVertex3f ( l * mNear, b * mNear, -mNear );
278 | glEnd ();
279 | // Subview Far plane
280 | glBegin ( GL_LINE_LOOP );
281 | glVertex3f ( l * mFar, t * mFar, -mFar );
282 | glVertex3f ( r * mFar, t * mFar, -mFar );
283 | glVertex3f ( r * mFar, b * mFar, -mFar );
284 | glVertex3f ( l * mFar, b * mFar, -mFar );
285 | glEnd ();
286 | }
287 |
288 | glPopMatrix ();
289 | }
290 | */
291 |
292 | bool Camera3D::pointInFrustum ( float x, float y, float z )
293 | {
294 | int p;
295 | for ( p = 0; p < 6; p++ )
296 | if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 )
297 | return false;
298 | return true;
299 | }
300 |
301 | bool Camera3D::boxInFrustum ( Vector3DF bmin, Vector3DF bmax)
302 | {
303 | Vector3DF vmin, vmax;
304 | int p;
305 | bool ret = true;
306 | for ( p = 0; p < 6; p++ ) {
307 | vmin.x = ( frustum[p][0] > 0 ) ? bmin.x : bmax.x; // Determine nearest and farthest point to plane
308 | vmax.x = ( frustum[p][0] > 0 ) ? bmax.x : bmin.x;
309 | vmin.y = ( frustum[p][1] > 0 ) ? bmin.y : bmax.y;
310 | vmax.y = ( frustum[p][1] > 0 ) ? bmax.y : bmin.y;
311 | vmin.z = ( frustum[p][2] > 0 ) ? bmin.z : bmax.z;
312 | vmax.z = ( frustum[p][2] > 0 ) ? bmax.z : bmin.z;
313 | if ( frustum[p][0]*vmax.x + frustum[p][1]*vmax.y + frustum[p][2]*vmax.z + frustum[p][3] <= 0 ) return false; // If nearest point is outside, Box is outside
314 | else if ( frustum[p][0]*vmin.x + frustum[p][1]*vmin.y + frustum[p][2]*vmin.z + frustum[p][3] <= 0 ) ret = true; // If nearest inside and farthest point is outside, Box intersects
315 | }
316 | return ret; // No points found outside. Box must be inside.
317 |
318 | /* --- Original method - Slow yet simpler.
319 | int p;
320 | for ( p = 0; p < 6; p++ ) {
321 | if( frustum[p][0] * bmin.x + frustum[p][1] * bmin.y + frustum[p][2] * bmin.z + frustum[p][3] > 0 ) continue;
322 | if( frustum[p][0] * bmax.x + frustum[p][1] * bmin.y + frustum[p][2] * bmin.z + frustum[p][3] > 0 ) continue;
323 | if( frustum[p][0] * bmax.x + frustum[p][1] * bmin.y + frustum[p][2] * bmax.z + frustum[p][3] > 0 ) continue;
324 | if( frustum[p][0] * bmin.x + frustum[p][1] * bmin.y + frustum[p][2] * bmax.z + frustum[p][3] > 0 ) continue;
325 | if( frustum[p][0] * bmin.x + frustum[p][1] * bmax.y + frustum[p][2] * bmin.z + frustum[p][3] > 0 ) continue;
326 | if( frustum[p][0] * bmax.x + frustum[p][1] * bmax.y + frustum[p][2] * bmin.z + frustum[p][3] > 0 ) continue;
327 | if( frustum[p][0] * bmax.x + frustum[p][1] * bmax.y + frustum[p][2] * bmax.z + frustum[p][3] > 0 ) continue;
328 | if( frustum[p][0] * bmin.x + frustum[p][1] * bmax.y + frustum[p][2] * bmax.z + frustum[p][3] > 0 ) continue;
329 | return false;
330 | }
331 | return true;*/
332 | }
333 |
334 | void Camera3D::setOrbit ( Vector3DF angs, Vector3DF tp, float dist, float dolly )
335 | {
336 | setOrbit ( angs.x, angs.y, angs.z, tp, dist, dolly );
337 | }
338 |
339 | void Camera3D::setOrbit ( float ax, float ay, float az, Vector3DF tp, float dist, float dolly )
340 | {
341 | ang_euler.Set ( ax, ay, az );
342 | mOrbitDist = dist;
343 | mDolly = dolly;
344 | double dx, dy, dz;
345 | dx = cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) ;
346 | dy = sin ( ang_euler.y * DEGtoRAD );
347 | dz = cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD );
348 | from_pos.x = tp.x + (float) dx * mOrbitDist;
349 | from_pos.y = tp.y + (float) dy * mOrbitDist;
350 | from_pos.z = tp.z + (float) dz * mOrbitDist;
351 | to_pos = tp;
352 | //to_pos.x = from_pos.x - (float) dx * mDolly;
353 | //to_pos.y = from_pos.y - (float) dy * mDolly;
354 | //to_pos.z = from_pos.z - (float) dz * mDolly;
355 | updateMatricies ();
356 | }
357 |
358 | void Camera3D::moveOrbit ( float ax, float ay, float az, float dd )
359 | {
360 | ang_euler += Vector3DF(ax,ay,az);
361 | mOrbitDist += dd;
362 |
363 | double dx, dy, dz;
364 | dx = cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) ;
365 | dy = sin ( ang_euler.y * DEGtoRAD );
366 | dz = cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD );
367 | from_pos.x = to_pos.x + (float) dx * mOrbitDist;
368 | from_pos.y = to_pos.y + (float) dy * mOrbitDist;
369 | from_pos.z = to_pos.z + (float) dz * mOrbitDist;
370 | updateMatricies ();
371 | }
372 |
373 | void Camera3D::moveToPos ( float tx, float ty, float tz )
374 | {
375 | to_pos += Vector3DF(tx,ty,tz);
376 |
377 | double dx, dy, dz;
378 | dx = cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) ;
379 | dy = sin ( ang_euler.y * DEGtoRAD );
380 | dz = cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD );
381 | from_pos.x = to_pos.x + (float) dx * mOrbitDist;
382 | from_pos.y = to_pos.y + (float) dy * mOrbitDist;
383 | from_pos.z = to_pos.z + (float) dz * mOrbitDist;
384 | updateMatricies ();
385 | }
386 |
387 | void Camera3D::Copy ( Camera3D& op )
388 | {
389 | mDolly = op.mDolly;
390 | mOrbitDist = op.mOrbitDist;
391 | from_pos = op.from_pos;
392 | to_pos = op.to_pos;
393 | ang_euler = op.ang_euler;
394 | mProjType = op.mProjType;
395 | mAspect = op.mAspect;
396 | mFov = op.mFov;
397 | mNear = op.mNear;
398 | mFar = op.mFar;
399 | updateMatricies ();
400 | }
401 |
402 | void Camera3D::setAngles ( float ax, float ay, float az )
403 | {
404 | ang_euler = Vector3DF(ax,ay,az);
405 | to_pos.x = from_pos.x - (float) (cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) * mDolly);
406 | to_pos.y = from_pos.y - (float) (sin ( ang_euler.y * DEGtoRAD ) * mDolly);
407 | to_pos.z = from_pos.z - (float) (cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD ) * mDolly);
408 | updateMatricies ();
409 | }
410 |
411 |
412 | void Camera3D::moveRelative ( float dx, float dy, float dz )
413 | {
414 | Vector3DF vec ( dx, dy, dz );
415 | vec *= invrot_matrix;
416 | to_pos += vec;
417 | from_pos += vec;
418 | updateMatricies ();
419 | }
420 |
421 | void Camera3D::setProjection (eProjection proj_type)
422 | {
423 | mProjType = proj_type;
424 | }
425 |
426 | void Camera3D::updateMatricies ()
427 | {
428 | Matrix4F basis;
429 | Vector3DF temp;
430 |
431 | // compute camera direction vectors --- MATCHES OpenGL's gluLookAt function (DO NOT MODIFY)
432 | dir_vec = to_pos; // f vector in gluLookAt docs
433 | dir_vec -= from_pos; // eye = from_pos in gluLookAt docs
434 | dir_vec.Normalize ();
435 | side_vec = dir_vec;
436 | side_vec.Cross ( up_dir );
437 | side_vec.Normalize ();
438 | up_vec = side_vec;
439 | up_vec.Cross ( dir_vec );
440 | up_vec.Normalize();
441 | dir_vec *= -1;
442 |
443 | // construct view matrix
444 | rotate_matrix.Basis (side_vec, up_vec, dir_vec );
445 | view_matrix = rotate_matrix;
446 | view_matrix.PreTranslate ( Vector3DF(-from_pos.x, -from_pos.y, -from_pos.z ) );
447 |
448 | // construct projection matrix --- MATCHES OpenGL's gluPerspective function (DO NOT MODIFY)
449 | float sx = (float) tan ( mFov * DEGtoRAD/2.0f ) * mNear;
450 | float sy = sx / mAspect;
451 | proj_matrix = 0.0f;
452 | proj_matrix(0,0) = 2.0f*mNear / sx; // matches OpenGL definition
453 | proj_matrix(1,1) = 2.0f*mNear / sy;
454 | proj_matrix(2,2) = -(mFar + mNear)/(mFar - mNear); // C
455 | proj_matrix(2,3) = -(2.0f*mFar * mNear)/(mFar - mNear); // D
456 | proj_matrix(3,2) = -1.0f;
457 |
458 | // construct tile projection matrix --- MATCHES OpenGL's glFrustum function (DO NOT MODIFY)
459 | float l, r, t, b;
460 | l = -sx + 2.0f*sx*mTile.x; // Tile is in range 0 <= x,y <= 1
461 | r = -sx + 2.0f*sx*mTile.z;
462 | t = sy - 2.0f*sy*mTile.y;
463 | b = sy - 2.0f*sy*mTile.w;
464 | tileproj_matrix = 0.0f;
465 | tileproj_matrix(0,0) = 2.0f*mNear / (r - l);
466 | tileproj_matrix(1,1) = 2.0f*mNear / (t - b);
467 | tileproj_matrix(0,2) = (r + l) / (r - l); // A
468 | tileproj_matrix(1,2) = (t + b) / (t - b); // B
469 | tileproj_matrix(2,2) = proj_matrix(2,2); // C
470 | tileproj_matrix(2,3) = proj_matrix(2,3); // D
471 | tileproj_matrix(3,2) = -1.0f;
472 | tileproj_matrix = proj_matrix;
473 |
474 | // construct inverse rotate and inverse projection matrix
475 | Vector3DF tvz(0, 0, 0);
476 | invrot_matrix.InverseView ( view_matrix.GetDataF(), tvz ); // Computed using rule: "Inverse of a basis rotation matrix is its transpose." (So long as translation is taken out)
477 | invproj_matrix.InverseProj ( tileproj_matrix.GetDataF() );
478 |
479 | Matrix4F view_matrix_notranslation = view_matrix;
480 | view_matrix_notranslation(12) = 0.0f;
481 | view_matrix_notranslation(13) = 0.0f;
482 | view_matrix_notranslation(14) = 0.0f;
483 |
484 | invviewproj_matrix = tileproj_matrix;
485 | invviewproj_matrix *= view_matrix_notranslation;
486 | invviewproj_matrix.InvertTRS();
487 | updateFrustum();
488 | }
489 |
490 | void Camera3D::setModelMatrix ( float* mtx )
491 | {
492 | memcpy ( model_matrix.GetDataF(), mtx, sizeof(float)*16 );
493 | }
494 |
495 | void Camera3D::setMatrices(const float* view_mtx, const float* proj_mtx)
496 | {
497 | // Assign the matrices we have
498 | view_matrix = Matrix4F(view_mtx);
499 | proj_matrix = Matrix4F(proj_mtx);
500 |
501 | // Assign model matrix
502 | Matrix4F mdl_matrix(view_mtx);
503 | mdl_matrix.InvertTRS();
504 |
505 | // Extract position
506 | from_pos = Vector3DF(mdl_matrix(0, 3), mdl_matrix(1, 3), mdl_matrix(2, 3));
507 |
508 | // construct tile projection matrix --- MATCHES OpenGL's glFrustum function (DO NOT MODIFY)
509 | tileproj_matrix = proj_matrix;
510 |
511 | // construct inverse rotate and inverse projection matrix
512 | Vector3DF tvz(0, 0, 0);
513 | invrot_matrix.InverseView(view_matrix.GetDataF(), tvz);
514 | invproj_matrix.InverseProj(tileproj_matrix.GetDataF());
515 |
516 | Matrix4F view_matrix_notranslation = view_matrix;
517 | view_matrix_notranslation(12) = 0.0f;
518 | view_matrix_notranslation(13) = 0.0f;
519 | view_matrix_notranslation(14) = 0.0f;
520 |
521 | invviewproj_matrix = tileproj_matrix;
522 | invviewproj_matrix *= view_matrix_notranslation;
523 | invviewproj_matrix.InvertTRS();
524 |
525 | // mFov, mAspect, mNear, mFar
526 | mNear = (2.0f * proj_matrix(2, 3)) / (2.0f * proj_matrix(2, 2) - 2.0f);
527 | mFar = ((proj_matrix(2, 2) - 1.0f) * mNear) / (proj_matrix(2, 2) + 1.0);
528 | float sx = 2.0f * mNear / proj_matrix(0, 0);
529 | float sy = 2.0f * mFar / proj_matrix(1, 1);
530 | mAspect = sx / sy;
531 | mFov = atan(sx / mNear) * 2.0f / DEGtoRAD;
532 |
533 | updateFrustum();
534 | }
535 |
536 | void Camera3D::setViewMatrix ( float* mtx, float* invmtx )
537 | {
538 | memcpy ( view_matrix.GetDataF(), mtx, sizeof(float)*16 );
539 | memcpy ( invrot_matrix.GetDataF(), invmtx, sizeof(float)*16 );
540 | }
541 | void Camera3D::setProjMatrix ( float* mtx, float* invmtx )
542 | {
543 | memcpy ( proj_matrix.GetDataF(), mtx, sizeof(float)*16 );
544 | memcpy ( tileproj_matrix.GetDataF(), mtx, sizeof(float)*16 );
545 | memcpy ( invproj_matrix.GetDataF(), invmtx, sizeof(float)*16 );
546 | }
547 |
548 | void Camera3D::updateFrustum ()
549 | {
550 | Matrix4F mv;
551 | mv = tileproj_matrix; // Compute the model-view-projection matrix
552 | mv *= view_matrix;
553 | float* mvm = mv.GetDataF();
554 | float t;
555 |
556 | // Right plane
557 | frustum[0][0] = mvm[ 3] - mvm[ 0];
558 | frustum[0][1] = mvm[ 7] - mvm[ 4];
559 | frustum[0][2] = mvm[11] - mvm[ 8];
560 | frustum[0][3] = mvm[15] - mvm[12];
561 | t = sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] );
562 | frustum[0][0] /= t; frustum[0][1] /= t; frustum[0][2] /= t; frustum[0][3] /= t;
563 | // Left plane
564 | frustum[1][0] = mvm[ 3] + mvm[ 0];
565 | frustum[1][1] = mvm[ 7] + mvm[ 4];
566 | frustum[1][2] = mvm[11] + mvm[ 8];
567 | frustum[1][3] = mvm[15] + mvm[12];
568 | t = sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] );
569 | frustum[1][0] /= t; frustum[1][1] /= t; frustum[1][2] /= t; frustum[1][3] /= t;
570 | // Bottom plane
571 | frustum[2][0] = mvm[ 3] + mvm[ 1];
572 | frustum[2][1] = mvm[ 7] + mvm[ 5];
573 | frustum[2][2] = mvm[11] + mvm[ 9];
574 | frustum[2][3] = mvm[15] + mvm[13];
575 | t = sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] );
576 | frustum[2][0] /= t; frustum[2][1] /= t; frustum[2][2] /= t; frustum[2][3] /= t;
577 | // Top plane
578 | frustum[3][0] = mvm[ 3] - mvm[ 1];
579 | frustum[3][1] = mvm[ 7] - mvm[ 5];
580 | frustum[3][2] = mvm[11] - mvm[ 9];
581 | frustum[3][3] = mvm[15] - mvm[13];
582 | t = sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] );
583 | frustum[3][0] /= t; frustum[3][1] /= t; frustum[3][2] /= t; frustum[3][3] /= t;
584 | // Far plane
585 | frustum[4][0] = mvm[ 3] - mvm[ 2];
586 | frustum[4][1] = mvm[ 7] - mvm[ 6];
587 | frustum[4][2] = mvm[11] - mvm[10];
588 | frustum[4][3] = mvm[15] - mvm[14];
589 | t = sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] );
590 | frustum[4][0] /= t; frustum[4][1] /= t; frustum[4][2] /= t; frustum[4][3] /= t;
591 | // Near plane
592 | frustum[5][0] = mvm[ 3] + mvm[ 2];
593 | frustum[5][1] = mvm[ 7] + mvm[ 6];
594 | frustum[5][2] = mvm[11] + mvm[10];
595 | frustum[5][3] = mvm[15] + mvm[14];
596 | t = sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] );
597 | frustum[5][0] /= t; frustum[5][1] /= t; frustum[5][2] /= t; frustum[5][3] /= t;
598 |
599 | tlRayWorld = inverseRayProj(-1.0f, 1.0f, 1.0f);
600 | trRayWorld = inverseRayProj(1.0f, 1.0f, 1.0f);
601 | blRayWorld = inverseRayProj(-1.0f, -1.0f, 1.0f);
602 | brRayWorld = inverseRayProj(1.0f, -1.0f, 1.0f);
603 | }
604 |
605 | float Camera3D::calculateLOD ( Vector3DF pnt, float minlod, float maxlod, float maxdist )
606 | {
607 | Vector3DF vec = pnt;
608 | vec -= from_pos;
609 | float lod = minlod + ((float) vec.Length() * (maxlod-minlod) / maxdist );
610 | lod = (lod < minlod) ? minlod : lod;
611 | lod = (lod > maxlod) ? maxlod : lod;
612 | return lod;
613 | }
614 |
615 | float Camera3D::getDu ()
616 | {
617 | return (float) tan ( mFov * DEGtoRAD/2.0f ) * mNear;
618 | }
619 | float Camera3D::getDv ()
620 | {
621 | return (float) tan ( mFov * DEGtoRAD/2.0f ) * mNear / mAspect;
622 | }
623 |
624 | Vector3DF Camera3D::getU ()
625 | {
626 | return side_vec;
627 | }
628 | Vector3DF Camera3D::getV ()
629 | {
630 | return up_vec;
631 | }
632 | Vector3DF Camera3D::getW ()
633 | {
634 | return dir_vec;
635 | }
636 |
637 |
638 | /*void Camera3D::setModelMatrix ()
639 | {
640 | glGetFloatv ( GL_MODELVIEW_MATRIX, model_matrix.GetDataF() );
641 | }
642 | void Camera3D::setModelMatrix ( Matrix4F& model )
643 | {
644 | model_matrix = model;
645 | mv_matrix = model;
646 | mv_matrix *= view_matrix;
647 | #ifdef USE_DX
648 |
649 | #else
650 | glLoadMatrixf ( mv_matrix.GetDataF() );
651 | #endif
652 | }
653 | */
654 |
655 | Vector3DF Camera3D::inverseRayProj(float x, float y, float z)
656 | {
657 | Vector4DF p(x, y, z, 1.0f);
658 |
659 | Vector4DF wp(0.0f, 0.0f, 0.0f, 0.0f);
660 | wp.x = invviewproj_matrix.data[0] * p.x + invviewproj_matrix.data[4] * p.y + invviewproj_matrix.data[8] * p.z + invviewproj_matrix.data[12];
661 | wp.y = invviewproj_matrix.data[1] * p.x + invviewproj_matrix.data[5] * p.y + invviewproj_matrix.data[9] * p.z + invviewproj_matrix.data[13];
662 | wp.z = invviewproj_matrix.data[2] * p.x + invviewproj_matrix.data[6] * p.y + invviewproj_matrix.data[10] * p.z + invviewproj_matrix.data[14];
663 | wp.w = invviewproj_matrix.data[3] * p.x + invviewproj_matrix.data[7] * p.y + invviewproj_matrix.data[11] * p.z + invviewproj_matrix.data[15];
664 |
665 | return Vector3DF(wp.x / wp.w, wp.y / wp.w, wp.z / wp.w);
666 | }
667 |
668 | Vector3DF Camera3D::inverseRay (float x, float y, float z)
669 | {
670 | float sx = (float) tan ( mFov * DEGtoRAD/2.0f);
671 | float sy = sx / mAspect;
672 | float tu, tv;
673 | tu = mTile.x + x * (mTile.z-mTile.x);
674 | tv = mTile.y + y * (mTile.w-mTile.y);
675 | Vector4DF pnt ( (tu*2.0f-1.0f) * z*sx, (1.0f-tv*2.0f) * z*sy, -z, 1 );
676 | pnt *= invrot_matrix;
677 | return pnt;
678 | }
679 |
680 | Vector3DF Camera3D::inverseRay ( float x, float y )
681 | {
682 | float sx = (float) tan ( mFov * DEGtoRAD/2.0f);
683 | float sy = sx / mAspect;
684 | float tu, tv;
685 | tu = mTile.x + (x/mXres) * (mTile.z-mTile.x);
686 | tv = mTile.y + (y/mYres) * (mTile.w-mTile.y);
687 | Vector4DF pnt ( (tu-0.5f) * sx*mNear, (0.5f-tv) *sy*mNear, -mNear, 1 );
688 | pnt *= invrot_matrix;
689 | pnt.Normalize ();
690 | return pnt;
691 | }
692 |
693 | Vector4DF Camera3D::project ( Vector3DF& p, Matrix4F& vm )
694 | {
695 | Vector4DF q = p; // World coordinates
696 | q.w = 1.0;
697 |
698 | q *= vm; // Eye coordinates
699 |
700 | q *= tileproj_matrix; // Projection
701 |
702 | q /= q.w; // Normalized Device Coordinates (w-divide)
703 |
704 | q.x = (q.x*0.5f+0.5f) / mXres;
705 | q.y = (q.y*0.5f+0.5f) / mYres;
706 | q.z = q.z*0.5f + 0.5f; // Stored depth buffer value
707 |
708 | return q;
709 | }
710 |
711 | Vector4DF Camera3D::project ( Vector3DF& p )
712 | {
713 | Vector4DF q = p; // World coordinates
714 | q.w = 1.0;
715 | q *= view_matrix; // Eye coordinates
716 |
717 | q *= tileproj_matrix; // Clip coordinates
718 |
719 | q /= q.w; // Normalized Device Coordinates (w-divide)
720 |
721 | q.x = (q.x*0.5f+0.5f)*mXres;
722 | q.y = (0.5f-q.y*0.5f)*mYres;
723 | q.z = q.z*0.5f + 0.5f; // Stored depth buffer value
724 |
725 | return q;
726 | }
727 |
728 | void PivotX::setPivot ( float x, float y, float z, float rx, float ry, float rz )
729 | {
730 | from_pos.Set ( x,y,z);
731 | ang_euler.Set ( rx,ry,rz );
732 | }
733 |
734 | void PivotX::updateTform ()
735 | {
736 | trans.RotateZYXT ( ang_euler, from_pos );
737 | }
738 |
739 |
--------------------------------------------------------------------------------
/helpers/camera.h:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------------------------------
2 | // NVIDIA(R) GVDB VOXELS
3 | // Copyright 2017, NVIDIA Corporation.
4 | //
5 | // Redistribution and use in source and binary forms, with or without modification,
6 | // are permitted provided that the following conditions are met:
7 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
9 | // in the documentation and/or other materials provided with the distribution.
10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
11 | // from this software without specific prior written permission.
12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
13 | // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
14 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
16 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 | //
19 | // Version 1.0: Rama Hoetzlein, 5/1/2017
20 | //----------------------------------------------------------------------------------
21 |
22 | #include "vec.h"
23 |
24 | #ifndef DEF_PIVOTX
25 | #define DEF_PIVOTX
26 |
27 | class PivotX {
28 | public:
29 | PivotX() { from_pos.Set(0,0,0); to_pos.Set(0,0,0); ang_euler.Set(0,0,0); scale.Set(1,1,1); trans.Identity(); }
30 | PivotX( Vector3DF& f, Vector3DF& t, Vector3DF& s, Vector3DF& a) { from_pos=f; to_pos=t; scale=s; ang_euler=a; }
31 |
32 | void setPivot ( float x, float y, float z, float rx, float ry, float rz );
33 | void setPivot ( Vector3DF& pos, Vector3DF& ang ) { from_pos = pos; ang_euler = ang; }
34 | void setPivot ( PivotX piv ) { from_pos = piv.from_pos; to_pos = piv.to_pos; ang_euler = piv.ang_euler; updateTform(); }
35 | void setPivot ( PivotX& piv ) { from_pos = piv.from_pos; to_pos = piv.to_pos; ang_euler = piv.ang_euler; updateTform(); }
36 |
37 | void setIdentity () { from_pos.Set(0,0,0); to_pos.Set(0,0,0); ang_euler.Set(0,0,0); scale.Set(1,1,1); trans.Identity(); }
38 |
39 | void setAng ( float rx, float ry, float rz ) { ang_euler.Set(rx,ry,rz); updateTform(); }
40 | void setAng ( Vector3DF& a ) { ang_euler = a; updateTform(); }
41 |
42 | void setPos ( float x, float y, float z ) { from_pos.Set(x,y,z); updateTform(); }
43 | void setPos ( Vector3DF& p ) { from_pos = p; updateTform(); }
44 |
45 | void setToPos ( float x, float y, float z ) { to_pos.Set(x,y,z); updateTform(); }
46 |
47 | void updateTform ();
48 | void setTform ( Matrix4F& t ) { trans = t; }
49 | inline Matrix4F& getTform () { return trans; }
50 | inline float* getTformData () { return trans.GetDataF(); }
51 |
52 | // Pivot
53 | PivotX getPivot () { return PivotX(from_pos, to_pos, scale, ang_euler); }
54 | Vector3DF& getPos () { return from_pos; }
55 | Vector3DF& getToPos () { return to_pos; }
56 | Vector3DF& getAng () { return ang_euler; }
57 | Vector3DF getDir () {
58 | return to_pos - from_pos;
59 | }
60 |
61 | Vector3DF from_pos;
62 | Vector3DF to_pos;
63 | Vector3DF scale;
64 | Vector3DF ang_euler;
65 | Matrix4F trans;
66 |
67 | //Quatern ang_quat;
68 | //Quatern dang_quat;
69 | };
70 |
71 | #endif
72 |
73 | #ifndef DEF_CAMERA_3D
74 | #define DEF_CAMERA_3D
75 |
76 | #define DEG_TO_RAD (3.141592/180.0)
77 |
78 | class Camera3D : public PivotX {
79 | public:
80 | enum eProjection {
81 | Perspective = 0,
82 | Parallel = 1
83 | };
84 | Camera3D ();
85 | void Copy ( Camera3D& op );
86 |
87 | void draw_gl();
88 |
89 | // Camera settings
90 | void setAspect ( float asp ) { mAspect = asp; updateMatricies(); }
91 | void setPos ( float x, float y, float z ) { from_pos.Set(x,y,z); updateMatricies(); }
92 | void setToPos ( float x, float y, float z ) { to_pos.Set(x,y,z); updateMatricies(); }
93 | void setFov (float fov) { mFov = fov; updateMatricies(); }
94 | void setNearFar (float n, float f ) { mNear = n; mFar = f; updateMatricies(); }
95 | void setDist ( float d ) { mOrbitDist = d; updateMatricies(); }
96 | void setTile ( float x1, float y1, float x2, float y2 ) { mTile.Set ( x1, y1, x2, y2 ); updateMatricies(); }
97 | void setSize ( float w, float h ) { mXres=w; mYres=h; }
98 | void setProjection (eProjection proj_type);
99 | void setModelMatrix ( float* mtx );
100 | void setViewMatrix ( float* mtx, float* invmtx );
101 | void setProjMatrix ( float* mtx, float* invmtx );
102 | void setMatrices ( const float* view_mtx, const float* proj_mtx );
103 |
104 | // Camera motion
105 | void setOrbit ( float ax, float ay, float az, Vector3DF tp, float dist, float dolly );
106 | void setOrbit ( Vector3DF angs, Vector3DF tp, float dist, float dolly );
107 | void setAngles ( float ax, float ay, float az );
108 | void moveOrbit ( float ax, float ay, float az, float dist );
109 | void moveToPos ( float tx, float ty, float tz );
110 | void moveRelative ( float dx, float dy, float dz );
111 |
112 | // Frustum testing
113 | bool pointInFrustum ( float x, float y, float z );
114 | bool boxInFrustum ( Vector3DF bmin, Vector3DF bmax);
115 | float calculateLOD ( Vector3DF pnt, float minlod, float maxlod, float maxdist );
116 |
117 | // Utility functions
118 | void updateMatricies (); // Updates camera axes and projection matricies
119 | void updateFrustum (); // Updates frustum planes
120 | Vector3DF inverseRay ( float x, float y, float z );
121 | Vector3DF inverseRay ( float x, float y );
122 | Vector3DF inverseRayProj ( float x, float y, float z );
123 | Vector4DF project ( Vector3DF& p );
124 | Vector4DF project ( Vector3DF& p, Matrix4F& vm ); // Project point - override view matrix
125 |
126 | void getVectors ( Vector3DF& dir, Vector3DF& up, Vector3DF& side ) { dir = dir_vec; up = up_vec; side = side_vec; }
127 | void getBounds ( float dst, Vector3DF& min, Vector3DF& max );
128 | float getNear () { return mNear; }
129 | float getFar () { return mFar; }
130 | float getFov () { return mFov; }
131 | float getDolly() { return mDolly; }
132 | float getOrbitDist() { return mOrbitDist; }
133 | Vector3DF& getUpDir () { return up_dir; }
134 | Vector4DF& getTile () { return mTile; }
135 | Matrix4F& getInvViewProjMatrix () { return invviewproj_matrix; }
136 | Matrix4F& getViewMatrix () { return view_matrix; }
137 | Matrix4F& getInvView () { return invrot_matrix; }
138 | Matrix4F& getRotateMatrix () { return rotate_matrix; }
139 | Matrix4F& getProjMatrix () { return tileproj_matrix; }
140 | Matrix4F& getFullProjMatrix () { return proj_matrix; }
141 | Matrix4F& getModelMatrix() { return model_matrix; }
142 | Matrix4F& getMVMatrix() { return mv_matrix; }
143 | float getAspect () { return mAspect; }
144 | Vector3DF getU ();
145 | Vector3DF getV ();
146 | Vector3DF getW ();
147 | float getDu ();
148 | float getDv ();
149 |
150 |
151 | public:
152 | eProjection mProjType; // Projection type
153 |
154 | // Camera Parameters // NOTE: Pivot maintains camera from and orientation
155 | float mDolly; // Camera to distance
156 | float mOrbitDist;
157 | float mFov, mAspect; // Camera field-of-view
158 | float mNear, mFar; // Camera frustum planes
159 | float mXres, mYres;
160 | Vector3DF dir_vec, side_vec, up_vec; // Camera aux vectors (W, V, and U)
161 | Vector3DF up_dir;
162 | Vector4DF mTile;
163 |
164 | // Transform Matricies
165 | Matrix4F invviewproj_matrix;
166 | Matrix4F rotate_matrix; // Vr matrix (rotation only)
167 | Matrix4F view_matrix; // V matrix (rotation + translation)
168 | Matrix4F proj_matrix; // P matrix
169 | Matrix4F invrot_matrix; // Vr^-1 matrix
170 | Matrix4F invproj_matrix;
171 | Matrix4F tileproj_matrix; // tiled projection matrix
172 | Matrix4F model_matrix;
173 | Matrix4F mv_matrix;
174 | float frustum[6][4]; // frustum plane equations
175 |
176 | bool mOps[8];
177 | int mWire;
178 |
179 | Vector4DF tlRayWorld;
180 | Vector4DF trRayWorld;
181 | Vector4DF blRayWorld;
182 | Vector4DF brRayWorld;
183 | };
184 |
185 | typedef Camera3D Light;
186 |
187 | #endif
188 |
--------------------------------------------------------------------------------
/helpers/directory.cpp:
--------------------------------------------------------------------------------
1 | #include "directory.h"
2 |
3 | #include "string_helper.h"
4 |
5 | #include
6 |
7 | #ifdef _MSC_VER
8 | #include
9 | #endif
10 |
11 | #ifdef BUILD_GCC
12 |
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #endif
25 |
26 | std::string Directory::gPathDelim = "\\";
27 |
28 | Directory::Directory ()
29 | {
30 | mPath = "";
31 | #ifdef _MSC_VER
32 | gPathDelim = "\\";
33 | #else
34 | gPathDelim = "/";
35 | #endif
36 | }
37 |
38 | std::string Directory::NormalizeSlashies( std::string path )
39 | {
40 | #ifdef _MSC_VER
41 | return strReplace( path, "/", "\\" );
42 | #else
43 | return strReplace( path, "\\", "/" );
44 | #endif
45 | }
46 |
47 |
48 | dir_list Directory::GetDirectoryItems( dir_list input )
49 | {
50 | dir_list out;
51 |
52 | for ( unsigned int i=0; i < input.size(); i++ ) {
53 | if ( input[i].type == FILE_TYPE_DIR && input[i].text != "." ) out.push_back( input[i] );
54 | }
55 | return out;
56 | }
57 |
58 | dir_list Directory::GetFileItems( dir_list input )
59 | {
60 | dir_list out;
61 |
62 | for ( unsigned int i=0; i < input.size(); i++ ){
63 | if ( input[i].type == FILE_TYPE_FILE && input[i].length >= 0 ) out.push_back( input[i] );
64 | }
65 | return out;
66 | }
67 |
68 |
69 | std::string Directory::GetExtension( std::string path )
70 | {
71 | path = Directory::NormalizeSlashies( path );
72 |
73 | std::vector< std::string > temp = strSplitMultiple ( path, "." );
74 | if ( temp.size() > 1 ) {
75 | return temp[ temp.size() ];
76 | }
77 | return "";
78 | }
79 |
80 |
81 | bool Directory::FileExists( std::string filename )
82 | {
83 | struct stat stFileInfo;
84 | bool exists = false;
85 | int intStat;
86 |
87 | intStat = stat( filename.c_str(), &stFileInfo );
88 |
89 | if(intStat == 0) {
90 | exists = true;
91 | }
92 |
93 | return( exists );
94 | }
95 |
96 |
97 | #ifdef _MSC_VER
98 |
99 | int Directory::CreateDir ( std::string path )
100 | {
101 | path = Directory::NormalizeSlashies( path );
102 |
103 | int out = 0;
104 |
105 | std::vector< std::string > pathSet = strSplitMultiple ( path, Directory::gPathDelim );
106 |
107 | std::string currPath = "";
108 |
109 | std::vector< std::string >::iterator it;
110 |
111 | for ( it = pathSet.begin() ; it < pathSet.end(); it++ ) {
112 |
113 | out = CreateDirectory ( (currPath + *it).c_str() , NULL );
114 |
115 | currPath += *it + Directory::gPathDelim ;
116 |
117 | if ( out == 0 ) {
118 | DWORD d = GetLastError();
119 | if ( d == ERROR_PATH_NOT_FOUND ) { return 0; }
120 | if ( d == ERROR_ALREADY_EXISTS ) { /* continue */ }
121 | }
122 |
123 | }
124 |
125 | return out;
126 | }
127 |
128 |
129 | std::string Directory::GetCollapsedPath( std::string path )
130 | {
131 | // Create a fully resolved path
132 | path = GetExecutablePath() + "/" + path;
133 |
134 | // Normalize slashes (\ vs /)
135 | path = Directory::NormalizeSlashies( path );
136 |
137 | elem_vec_t out;
138 | std::vector< std::string > temp;
139 | std::string mFileFound = "";
140 |
141 | // Split path
142 | temp = strSplitMultiple ( path, Directory::gPathDelim);
143 |
144 | for ( unsigned int i = 0; i < temp.size(); i++ ) {
145 | if ( ( temp[i].compare("..") == 0 ) && out.size() > 0 ) {
146 | out.pop_back();
147 | } else if ( temp[i].size() > 0 && temp[i].find(".") == -1 ) {
148 | text_element_t element;
149 | element.text = temp[i];
150 | element.length = -1;
151 | out.push_back( element );
152 | }
153 |
154 | if ( temp[i].find(".") != -1 ) {
155 | mFileFound = temp[i];
156 | }
157 | }
158 |
159 | std::string outStr = "";
160 |
161 | for ( unsigned int k = 0; k < out.size(); k++ )
162 | {
163 | outStr += out[k].text;
164 | outStr += Directory::gPathDelim;
165 | }
166 |
167 | // remember to remove the last extraneous slashies
168 | return outStr.substr( 0, outStr.length() - 1 );
169 | }
170 |
171 | std::string Directory::GetExecutablePath()
172 | {
173 | LPTSTR szAppPath[MAX_PATH];
174 |
175 | std::string strAppDirectory;
176 |
177 | ::GetModuleFileName(NULL, szAppPath[0], (sizeof(szAppPath) - 1)/sizeof(TCHAR));
178 |
179 | // Extract directory
180 | strAppDirectory = (char*) szAppPath; // use ws2s for conversion to wchar
181 | strAppDirectory = strAppDirectory.substr(0, strAppDirectory.rfind("\\"));
182 |
183 | strAppDirectory = strReplace( strAppDirectory, "\\", "/" );
184 |
185 | return strAppDirectory;
186 | }
187 |
188 | std::string Directory::ws2s(const std::wstring& s)
189 | {
190 | int len;
191 | int slength = (int)s.length() + 1;
192 | len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
193 | char* buf = (char*) malloc ( len ); // temporary, don't register with memory checker
194 | WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
195 | std::string r(buf);
196 | free ( buf );
197 | return r;
198 | }
199 |
200 | std::wstring Directory::s2ws(const std::string& s)
201 | {
202 | int len;
203 | int slength = (int)s.length() + 1;
204 | len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
205 | wchar_t* buf = (wchar_t*) malloc ( len *sizeof(wchar_t) ); // temporary, don't register with memory checker
206 | MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
207 | std::wstring r(buf);
208 | free ( buf );
209 | return r;
210 | }
211 |
212 | void Directory::LoadDir ( std::string path, std::string ext )
213 | {
214 | mPath = path;
215 | mFileFilter = ext;
216 | mList = DirList ( path, ext );
217 | }
218 |
219 | dir_list Directory::DirList( std::string path, std::string ext )
220 | {
221 | path = Directory::NormalizeSlashies( path ) + ext;
222 |
223 | //NOTE this is not unicode compliant
224 | WIN32_FIND_DATAA fileData;
225 | HANDLE hFind = INVALID_HANDLE_VALUE;
226 | LARGE_INTEGER filesize;
227 |
228 | DWORD dwError=0;
229 |
230 | dir_list out;
231 |
232 | hFind = FindFirstFileA( path.c_str(), &fileData );
233 |
234 | if (INVALID_HANDLE_VALUE == hFind)
235 | {
236 | //
237 | }
238 |
239 | do
240 | {
241 | if (( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && !( fileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ))
242 | {
243 | dir_list_element e;
244 | e.length = 0;
245 | e.text = fileData.cFileName;
246 | e.extension = "DIR";
247 | e.type = FILE_TYPE_DIR;
248 | out.push_back( e );
249 | }
250 | else
251 | {
252 | filesize.LowPart = fileData.nFileSizeLow;
253 | filesize.HighPart = fileData.nFileSizeHigh;
254 |
255 | dir_list_element e;
256 | e.length = (int) filesize.QuadPart;
257 | e.text = fileData.cFileName;
258 | e.extension = strSplitArg ( e.text, "." );
259 | e.type = FILE_TYPE_FILE;
260 | out.push_back( e );
261 | }
262 | }
263 | while (FindNextFileA(hFind, &fileData) != 0);
264 |
265 | dwError = GetLastError();
266 | if (dwError != ERROR_NO_MORE_FILES)
267 | {
268 | //
269 | }
270 |
271 | FindClose(hFind);
272 | return out;
273 | }
274 | #endif
275 |
276 | #ifdef BUILD_GCC
277 | //#ifdef __LINUX
278 |
279 | // DUMMY!!!
280 | int Directory::CreatePath( std::string path ) {
281 | return 0;
282 | }
283 |
284 | std::string Directory::GetExecutablePath()
285 | {
286 | char result[ PATH_MAX ];
287 | ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
288 | return std::string( result, (count > 0) ? count : 0 );
289 | }
290 |
291 | /****************
292 | * PROBABLY NOT WORKING!!
293 | ****************/
294 | dir_list Directory::DirList( std::string path )
295 | {
296 | path = Directory::NormalizeSlashies( path );
297 |
298 | dir_list out;
299 |
300 | DIR *dp;
301 | struct dirent *dirp;
302 | if( ( dp = opendir( path.c_str() ) ) == NULL ) {
303 | //cout << "Error(" << errno << ") opening " << dir << endl;
304 | printf("Error(%i) opening\n", errno);
305 | //return dir_list;
306 | return out;
307 | }
308 |
309 | while ( (dirp = readdir( dp ) ) != NULL ) {
310 |
311 | dir_list_element e;
312 | e.length = dirp->d_reclen;
313 | e.text = std::string( dirp->d_name );
314 | //e.extension = "DIR";
315 | //e.type = FILE_TYPE_DIR;
316 | out.push_back( e );
317 |
318 | }
319 |
320 | closedir( dp );
321 | //return 0;
322 | return out;
323 | }
324 |
325 | std::string Directory::GetCollapsedPath( std::string path )
326 | {
327 | path = Directory::NormalizeSlashies( path );
328 |
329 | elem_vec_t out;
330 | std::vector< std::string > temp;
331 |
332 | std::string mFileFound = "";
333 |
334 | temp = StringHelper::SplitString( path, Directory::mPathDelim);
335 |
336 | for ( unsigned int i = 0; i < temp.size(); i++ )
337 | {
338 | if ( ( temp[i].compare("..") == 0 ) && out.size() > 0 ) {
339 | out.pop_back();
340 | } else if ( temp[i].size() > 0 && temp[i].find(".") == -1 ) {
341 | text_element_t element;
342 | element.text = temp[i];
343 | element.length = -1;
344 | out.push_back( element );
345 | }
346 |
347 | if ( temp[i].find(".") != -1 ) {
348 | mFileFound = temp[i];
349 | }
350 | }
351 |
352 | std::string outStr = "";
353 |
354 | for ( unsigned int k = 0; k < out.size(); k++ )
355 | {
356 | outStr += out[k].text;
357 | outStr += Directory::mPathDelim;
358 | }
359 |
360 | // remember to remove the last extraneous slashies
361 | return outStr.substr( 0, outStr.length() - 1 );
362 | }
363 |
364 |
365 | #endif
366 |
--------------------------------------------------------------------------------
/helpers/directory.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef DEF_DIR_OBJECT
3 | #define DEF_DIR_OBJECT
4 |
5 | //#include "common_defs.h"
6 | #include
7 |
8 | #define FILE_TYPE_DIR 0
9 | #define FILE_TYPE_FILE 1
10 |
11 | // Hmmm - have to factor this specific stuff out.
12 | #define FILE_TYPE_BLOCKSAVE 2
13 | #define FILE_TYPE_BLOCKLEV 3
14 |
15 | typedef struct {
16 | int type;
17 | std::string text;
18 | std::string extension;
19 | int length;
20 | } dir_list_element;
21 |
22 | typedef std::vector< dir_list_element > dir_list;
23 |
24 | typedef struct {
25 | std::string text;
26 | float length;
27 | } text_element_t;
28 |
29 | typedef std::vector< text_element_t > elem_vec_t;
30 |
31 |
32 | class Directory {
33 | public:
34 | Directory ();
35 |
36 | void LoadDir ( std::string path, std::string filter );
37 | int CreateDir ( std::string path );
38 | int getNumFiles () { return (int) mList.size(); }
39 | dir_list_element getFile ( int n ) { return mList[n]; }
40 | bool isDir ( int n ) { return mList[n].type==0; }
41 |
42 | // Static functions
43 | static dir_list DirList( std::string path, std::string filter );
44 | static bool FileExists( std::string filename );
45 | static std::string ws2s(const std::wstring& s);
46 | static std::wstring s2ws(const std::string& s);
47 | static dir_list GetFileItems( dir_list input);
48 | static dir_list GetDirectoryItems( dir_list input);
49 | static std::string NormalizeSlashies( std::string path );
50 | static std::string GetExtension( std::string path );
51 | static std::string GetExecutablePath();
52 | static std::string GetCollapsedPath( std::string path );
53 | static std::string gPathDelim;
54 |
55 | std::string getPath () { return mPath; }
56 | std::string getFilter () { return mFileFilter; }
57 |
58 | private:
59 |
60 | std::string mPath;
61 | std::string mFileFilter;
62 |
63 |
64 | dir_list mList;
65 |
66 | };
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/helpers/file_tga.cpp:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------------------------------
2 | // NVIDIA(R) GVDB VOXELS
3 | // Copyright 2017, NVIDIA Corporation.
4 | //
5 | // Redistribution and use in source and binary forms, with or without modification,
6 | // are permitted provided that the following conditions are met:
7 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
9 | // in the documentation and/or other materials provided with the distribution.
10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
11 | // from this software without specific prior written permission.
12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
13 | // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
14 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
16 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 | //
19 | // Version 1.0: Rama Hoetzlein, 5/1/2017
20 | //----------------------------------------------------------------------------------
21 |
22 |
23 | //------------------------------------------------ TGA FORMAT
24 | #ifndef TGA_NOIMPL
25 |
26 | #include "file_tga.h"
27 |
28 | #ifdef DEBUG_HEAP
29 | #define _CRTDBG_MAP_ALLOC
30 | #include
31 | #include
32 | #else
33 | #include
34 | #endif
35 |
36 |
37 | TGA::~TGA( void )
38 | {
39 | if( m_nImageData != NULL )
40 | {
41 | free( m_nImageData );
42 | m_nImageData = NULL;
43 | }
44 | }
45 |
46 | int TGA::returnError( FILE *s, int error )
47 | {
48 | // Called when there is an error loading the .tga texture file.
49 | fclose( s );
50 | return error;
51 | }
52 |
53 | unsigned char *TGA::getRGBA( FILE *s, int size )
54 | {
55 | // Read in RGBA data for a 32bit image.
56 | unsigned char *rgba;
57 | unsigned char temp;
58 | int bread;
59 | int i;
60 |
61 | rgba = (unsigned char *) malloc( size * 4 );
62 |
63 | if( rgba == NULL )
64 | return 0;
65 |
66 | bread = (int) fread( rgba, sizeof (unsigned char), size * 4, s );
67 |
68 | // TGA is stored in BGRA, make it RGBA
69 | if( bread != size * 4 )
70 | {
71 | free( rgba );
72 | return 0;
73 | }
74 |
75 | for( i = 0; i < size * 4; i += 4 )
76 | {
77 | temp = rgba[i];
78 | rgba[i] = rgba[i + 2];
79 | rgba[i + 2] = temp;
80 | }
81 |
82 | m_texFormat = TGA::RGBA;
83 | return rgba;
84 | }
85 |
86 | unsigned char *TGA::getRGB( FILE *s, int size )
87 | {
88 | // Read in RGB data for a 24bit image.
89 | unsigned char *rgb;
90 | unsigned char temp;
91 | int bread;
92 | int i;
93 |
94 | rgb = (unsigned char*)malloc( size * 3 );
95 |
96 | if( rgb == NULL )
97 | return 0;
98 |
99 | bread = (int)fread( rgb, sizeof (unsigned char), size * 3, s );
100 |
101 | if(bread != size * 3)
102 | {
103 | free( rgb );
104 | return 0;
105 | }
106 |
107 | // TGA is stored in BGR, make it RGB
108 | for( i = 0; i < size * 3; i += 3 )
109 | {
110 | temp = rgb[i];
111 | rgb[i] = rgb[i + 2];
112 | rgb[i + 2] = temp;
113 | }
114 |
115 | m_texFormat = TGA::RGB;
116 |
117 | return rgb;
118 | }
119 |
120 | unsigned char *TGA::getGray( FILE *s, int size )
121 | {
122 | // Gets the grayscale image data. Used as an alpha channel.
123 | unsigned char *grayData;
124 | int bread;
125 |
126 | grayData = (unsigned char*)malloc( size );
127 |
128 | if( grayData == NULL )
129 | return 0;
130 |
131 | bread = (int)fread( grayData, sizeof (unsigned char), size, s );
132 |
133 | if( bread != size )
134 | {
135 | free( grayData );
136 | return 0;
137 | }
138 |
139 | m_texFormat = TGA::ALPHA;
140 |
141 | return grayData;
142 | }
143 |
144 | #pragma warning(disable: 4996)
145 |
146 | TGA::TGAError TGA::load( const char *name )
147 | {
148 | // Loads up a targa file. Supported types are 8,24 and 32
149 | // uncompressed images.
150 | unsigned char type[4];
151 | unsigned char info[7];
152 | FILE *s = NULL;
153 | int size = 0;
154 |
155 | if( !(s = fopen( name, "rb" )) )
156 | return TGA_FILE_NOT_FOUND;
157 |
158 | fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
159 | fseek( s, 12, SEEK_SET); // Seek past the header and useless info
160 | fread( &info, sizeof (char), 6, s );
161 |
162 | if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
163 | returnError( s, TGA_BAD_IMAGE_TYPE );
164 |
165 | m_nImageWidth = info[0] + info[1] * 256;
166 | m_nImageHeight = info[2] + info[3] * 256;
167 | m_nImageBits = info[4];
168 |
169 | size = m_nImageWidth * m_nImageHeight;
170 |
171 | // Make sure we are loading a supported type
172 | if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
173 | returnError( s, TGA_BAD_BITS );
174 |
175 | if( m_nImageBits == 32 )
176 | m_nImageData = getRGBA( s, size );
177 | else if( m_nImageBits == 24 )
178 | m_nImageData = getRGB( s, size );
179 | else if( m_nImageBits == 8 )
180 | m_nImageData = getGray( s, size );
181 |
182 | // No image data
183 | if( m_nImageData == NULL )
184 | returnError( s, TGA_BAD_DATA );
185 |
186 | fclose( s );
187 |
188 | return TGA_NO_ERROR;
189 | }
190 |
191 | void TGA::writeRGBA( FILE *s, const unsigned char *externalImage, int size )
192 | {
193 | // Read in RGBA data for a 32bit image.
194 | unsigned char *rgba;
195 | int bread;
196 | int i;
197 |
198 | rgba = (unsigned char *)malloc( size * 4 );
199 |
200 | // switch RGBA to BGRA
201 | for( i = 0; i < size * 4; i += 4 )
202 | {
203 | rgba[i + 0] = externalImage[i + 2];
204 | rgba[i + 1] = externalImage[i + 1];
205 | rgba[i + 2] = externalImage[i + 0];
206 | rgba[i + 3] = externalImage[i + 3];
207 | }
208 |
209 | bread = (int)fwrite( rgba, sizeof (unsigned char), size * 4, s );
210 | free( rgba );
211 | }
212 |
213 | void TGA::writeRGB( FILE *s, const unsigned char *externalImage, int size )
214 | {
215 | // Read in RGBA data for a 32bit image.
216 | unsigned char *rgb;
217 | int bread;
218 | int i;
219 |
220 | rgb = (unsigned char *)malloc( size * 3 );
221 |
222 | // switch RGB to BGR
223 | for( i = 0; i < size * 3; i += 3 )
224 | {
225 | rgb[i + 0] = externalImage[i + 2];
226 | rgb[i + 1] = externalImage[i + 1];
227 | rgb[i + 2] = externalImage[i + 0];
228 | }
229 |
230 | bread = (int)fwrite( rgb, sizeof (unsigned char), size * 3, s );
231 | free( rgb );
232 | }
233 |
234 | void TGA::writeGrayAsRGB( FILE *s, const unsigned char *externalImage, int size )
235 | {
236 | // Read in RGBA data for a 32bit image.
237 | unsigned char *rgb;
238 | int bread;
239 | int i;
240 |
241 | rgb = (unsigned char *)malloc( size * 3 );
242 |
243 | // switch RGB to BGR
244 | int j = 0;
245 | for( i = 0; i < size * 3; i += 3, j++ )
246 | {
247 | rgb[i + 0] = externalImage[j];
248 | rgb[i + 1] = externalImage[j];
249 | rgb[i + 2] = externalImage[j];
250 | }
251 |
252 | bread = (int)fwrite( rgb, sizeof (unsigned char), size * 3, s );
253 | free( rgb );
254 | }
255 |
256 | void TGA::writeGray( FILE *s, const unsigned char *externalImage, int size )
257 | {
258 | // Gets the grayscale image data. Used as an alpha channel.
259 | int bread;
260 |
261 | bread = (int)fwrite( externalImage, sizeof (unsigned char), size, s );
262 | }
263 |
264 | TGA::TGAError TGA::saveFromExternalData( const char *name, int w, int h, TGA::TGAFormat fmt, const unsigned char *externalImage )
265 | {
266 | static unsigned char type[] = {0,0,2};
267 | static unsigned char dummy[] = {0,0,0,0,0,0,0,0,0};
268 | static unsigned char info[] = {0,0,0,0,0,0};
269 | FILE *s = NULL;
270 | int size = 0;
271 |
272 | if( !(s = fopen( name, "wb" )) )
273 | return TGA_FILE_NOT_FOUND;
274 |
275 | fwrite( type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
276 | fwrite( dummy, sizeof (char), 9, s ); // Read in colormap info and image type, byte 0 ignored
277 |
278 | info[0] = w & 0xFF;
279 | info[1] = (w>>8) & 0xFF;
280 | info[2] = h & 0xFF;
281 | info[3] = (h>>8) & 0xFF;
282 | switch(fmt)
283 | {
284 | case ALPHA:
285 | info[4] = 8;
286 | break;
287 | case RGB:
288 | info[4] = 24;
289 | break;
290 | case RGBA:
291 | info[4] = 32;
292 | break;
293 | }
294 | fwrite( info, sizeof (char), 6, s );
295 |
296 | size = w*h;
297 | switch(fmt)
298 | {
299 | case ALPHA:
300 | writeGray(s, externalImage, size);
301 | break;
302 | case RGB:
303 | writeGrayAsRGB/*writeRGB*/(s, externalImage, size);
304 | break;
305 | case RGBA:
306 | writeRGBA(s, externalImage, size);
307 | break;
308 | }
309 |
310 | fclose( s );
311 |
312 | return TGA_NO_ERROR;
313 | }
314 |
315 | #endif // #ifndef TGA_NOIMPL
316 |
317 |
--------------------------------------------------------------------------------
/helpers/file_tga.h:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------------------------------
2 | // NVIDIA(R) GVDB VOXELS
3 | // Copyright 2017, NVIDIA Corporation.
4 | //
5 | // Redistribution and use in source and binary forms, with or without modification,
6 | // are permitted provided that the following conditions are met:
7 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
9 | // in the documentation and/or other materials provided with the distribution.
10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
11 | // from this software without specific prior written permission.
12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
13 | // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
14 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
16 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 | //
19 | // Version 1.0: Rama Hoetzlein, 5/1/2017
20 | //----------------------------------------------------------------------------------
21 |
22 | #ifndef LOAD_TGA
23 |
24 | #include
25 |
26 | class TGA {
27 | public:
28 | enum TGAFormat
29 | {
30 | RGB = 0x1907,
31 | RGBA = 0x1908,
32 | ALPHA = 0x1906,
33 | UNKNOWN = -1
34 | };
35 |
36 | enum TGAError
37 | {
38 | TGA_NO_ERROR = 1, // No error
39 | TGA_FILE_NOT_FOUND, // File was not found
40 | TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
41 | TGA_BAD_DIMENSION, // Dimension is not a power of 2
42 | TGA_BAD_BITS, // Image bits is not 8, 24 or 32
43 | TGA_BAD_DATA // Image data could not be loaded
44 | };
45 |
46 | TGA(void) :
47 | m_texFormat(TGA::UNKNOWN),
48 | m_nImageWidth(0),
49 | m_nImageHeight(0),
50 | m_nImageBits(0),
51 | m_nImageData(NULL) {}
52 |
53 | ~TGA(void);
54 |
55 | TGA::TGAError load( const char *name );
56 | TGA::TGAError saveFromExternalData( const char *name, int w, int h, TGAFormat fmt, const unsigned char *externalImage );
57 |
58 | TGAFormat m_texFormat;
59 | int m_nImageWidth;
60 | int m_nImageHeight;
61 | int m_nImageBits;
62 | unsigned char * m_nImageData;
63 |
64 | private:
65 |
66 | int returnError(FILE *s, int error);
67 | unsigned char *getRGBA(FILE *s, int size);
68 | unsigned char *getRGB(FILE *s, int size);
69 | unsigned char *getGray(FILE *s, int size);
70 | void writeRGBA(FILE *s, const unsigned char *externalImage, int size);
71 | void writeRGB(FILE *s, const unsigned char *externalImage, int size);
72 | void writeGrayAsRGB(FILE *s, const unsigned char *externalImage, int size);
73 | void writeGray(FILE *s, const unsigned char *externalImage, int size);
74 | };
75 |
76 | #endif
--------------------------------------------------------------------------------
/helpers/main.h:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------------------------------
2 | // NVIDIA(R) GVDB VOXELS
3 | // Copyright 2017, NVIDIA Corporation.
4 | //
5 | // Redistribution and use in source and binary forms, with or without modification,
6 | // are permitted provided that the following conditions are met:
7 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
9 | // in the documentation and/or other materials provided with the distribution.
10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
11 | // from this software without specific prior written permission.
12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
13 | // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
14 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
16 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 | //
19 | // Version 1.0: Rama Hoetzlein, 5/1/2017
20 | //----------------------------------------------------------------------------------
21 |
22 | #ifndef __MAIN_H__
23 | #define __MAIN_H__
24 |
25 | #include
26 | #include
27 | #include
28 |
29 |
30 | #pragma warning(disable:4996) // preventing snprintf >> _snprintf_s
31 |
32 | // trick for pragma message so we can write:
33 | // #pragma message(__FILE__"("S__LINE__"): blah")
34 | #define S__(x) #x
35 | #define S_(x) S__(x)
36 | #define S__LINE__ S_(__LINE__)
37 |
38 | #ifdef DEBUG_HEAP
39 | #define _CRTDBG_MAP_ALLOC
40 | #include
41 | #include
42 | #else
43 | #include
44 | #endif
45 |
46 | #include
47 | #include
48 | #include
49 | #include