├── .gitignore ├── .travis.yml ├── Build ├── DirectX.props ├── DirectXMesh.props ├── VS2012 │ ├── Tootle.sln │ ├── TootleLib.vcxproj │ ├── TootleLib.vcxproj.filters │ ├── TootleLibSoftware.vcxproj │ ├── TootleLibSoftware.vcxproj.filters │ ├── TootleSample.vcxproj │ ├── TootleSample.vcxproj.filters │ ├── TootleSampleSoftware.vcxproj │ └── TootleSampleSoftware.vcxproj.filters ├── VS2013 │ ├── Tootle.sln │ ├── TootleLib.vcxproj │ ├── TootleLib.vcxproj.filters │ ├── TootleLibSoftware.vcxproj │ ├── TootleLibSoftware.vcxproj.filters │ ├── TootleSample.vcxproj │ ├── TootleSample.vcxproj.filters │ ├── TootleSampleSoftware.vcxproj │ └── TootleSampleSoftware.vcxproj.filters ├── VS2015 - DX11_1 │ ├── Tootle.sln │ ├── TootleLib.vcxproj │ ├── TootleLib.vcxproj.filters │ ├── TootleSample_DX11_1.vcxproj │ └── TootleSample_DX11_1.vcxproj.filters └── VS2015 │ ├── Tootle.sln │ ├── TootleLib.vcxproj │ ├── TootleLib.vcxproj.filters │ ├── TootleLibSoftware.vcxproj │ ├── TootleLibSoftware.vcxproj.filters │ ├── TootleSample.vcxproj │ ├── TootleSample.vcxproj.filters │ ├── TootleSampleSoftware.vcxproj │ └── TootleSampleSoftware.vcxproj.filters ├── LICENSE ├── README.md ├── Scripts └── FetchDependencies.py ├── appveyor.yml ├── bin └── runTest.bat ├── docs ├── tootle-i3d2006-paper.pdf ├── tootle-i3d2006-talk.pdf ├── tootle2-siggraph2007-paper.pdf └── tootle2-siggraph2007-talk.pdf ├── lib └── EMPTY.txt ├── meshes ├── Torus2.obj ├── bolt.obj ├── bolt2.obj ├── bunny.obj ├── cactus.obj └── fandisk.obj └── src ├── CMakeLists.txt ├── TootleLib ├── CMakeLists.txt ├── RayTracer │ ├── JRT │ │ ├── JRTBoundingBox.cpp │ │ ├── JRTBoundingBox.h │ │ ├── JRTCamera.cpp │ │ ├── JRTCamera.h │ │ ├── JRTCommon.h │ │ ├── JRTCore.cpp │ │ ├── JRTCore.h │ │ ├── JRTCoreUtils.cpp │ │ ├── JRTCoreUtils.h │ │ ├── JRTH2KDTreeBuilder.cpp │ │ ├── JRTH2KDTreeBuilder.h │ │ ├── JRTHeuristicKDTreeBuilder.cpp │ │ ├── JRTHeuristicKDTreeBuilder.h │ │ ├── JRTKDTree.cpp │ │ ├── JRTKDTree.h │ │ ├── JRTKDTreeBuilder.cpp │ │ ├── JRTKDTreeBuilder.h │ │ ├── JRTMesh.cpp │ │ ├── JRTMesh.h │ │ ├── JRTOrthoCamera.cpp │ │ ├── JRTOrthoCamera.h │ │ ├── JRTPPMImage.cpp │ │ ├── JRTPPMImage.h │ │ ├── JRTTriangleIntersection.cpp │ │ └── JRTTriangleIntersection.h │ ├── Math │ │ ├── JML.h │ │ ├── JMLFuncs.cpp │ │ ├── JMLFuncs.h │ │ ├── JMLMatrix.h │ │ ├── JMLSSEVec.h │ │ ├── JMLScalar.h │ │ ├── JMLVec2.h │ │ └── JMLVec3.h │ ├── TootleRaytracer.cpp │ ├── TootleRaytracer.h │ └── makefile ├── Stripifier.cpp ├── Stripifier.h ├── Timer.cpp ├── Timer.h ├── TootlePCH.h ├── aligned_malloc.cpp ├── aligned_malloc.h ├── bbox.h ├── cloud.h ├── clustering.cpp ├── clustering.h ├── color.h ├── d3doverdrawwindow.cpp ├── d3doverdrawwindow.h ├── d3dwindow.h ├── d3dwm.cpp ├── d3dwm.h ├── error.c ├── error.h ├── feedback.cpp ├── feedback.h ├── fit.cpp ├── fit.h ├── gdiwindow.h ├── gdiwm.cpp ├── gdiwm.h ├── heap.c ├── heap.h ├── include │ └── tootlelib.h ├── makefile ├── matrix.h ├── mesh.h ├── option.h ├── overdraw.cpp ├── overdraw.h ├── quaternion.h ├── scalar.h ├── soup.cpp ├── soup.h ├── souptomesh.cpp ├── souptomesh.h ├── tootlelib.cpp ├── triorder.cpp ├── triorder.h ├── vector.h ├── viewpoints.h └── window.h └── TootleSample ├── CMakeLists.txt ├── MaterialSort.cpp ├── ObjLoader.cpp ├── ObjLoader.h ├── Timer.cpp ├── Timer.h ├── Tootle.cpp ├── makefile └── option.h /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | *.VC.opendb 10 | 11 | # User-specific files (MonoDevelop/Xamarin Studio) 12 | *.userprefs 13 | 14 | # Build results 15 | [Dd]ebug/ 16 | [Dd]ebugPublic/ 17 | [Rr]elease/ 18 | [Rr]eleases/ 19 | x64/ 20 | x86/ 21 | bld/ 22 | [Bb]in/* 23 | !bin/runTest.bat 24 | [Oo]bj/ 25 | lib/* 26 | !lib/EMPTY.txt 27 | 28 | # Visual Studo 2015 cache/options directory 29 | .vs/ 30 | *.VC.db 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | !meshes/*.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opensdf 79 | *.sdf 80 | *.cachefile 81 | 82 | # Visual Studio profiler 83 | *.psess 84 | *.vsp 85 | *.vspx 86 | 87 | # TFS 2012 Local Workspace 88 | $tf/ 89 | 90 | # Guidance Automation Toolkit 91 | *.gpState 92 | 93 | # ReSharper is a .NET coding add-in 94 | _ReSharper*/ 95 | *.[Rr]e[Ss]harper 96 | *.DotSettings.user 97 | 98 | # JustCode is a .NET coding addin-in 99 | .JustCode 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | _NCrunch_* 109 | .*crunch*.local.xml 110 | 111 | # MightyMoose 112 | *.mm.* 113 | AutoTest.Net/ 114 | 115 | # Web workbench (sass) 116 | .sass-cache/ 117 | 118 | # Installshield output folder 119 | [Ee]xpress/ 120 | 121 | # DocProject is a documentation generator add-in 122 | DocProject/buildhelp/ 123 | DocProject/Help/*.HxT 124 | DocProject/Help/*.HxC 125 | DocProject/Help/*.hhc 126 | DocProject/Help/*.hhk 127 | DocProject/Help/*.hhp 128 | DocProject/Help/Html2 129 | DocProject/Help/html 130 | 131 | # Click-Once directory 132 | publish/ 133 | 134 | # Publish Web Output 135 | *.[Pp]ublish.xml 136 | *.azurePubxml 137 | # TODO: Comment the next line if you want to checkin your web deploy settings 138 | # but database connection strings (with potential passwords) will be unencrypted 139 | *.pubxml 140 | *.publishproj 141 | 142 | # NuGet Packages 143 | *.nupkg 144 | # The packages folder can be ignored because of Package Restore 145 | **/packages/* 146 | # except build/, which is used as an MSBuild target. 147 | !**/packages/build/ 148 | # Uncomment if necessary however generally it will be regenerated when needed 149 | #!**/packages/repositories.config 150 | 151 | # Windows Azure Build Output 152 | csx/ 153 | *.build.csdef 154 | 155 | # Windows Store app package directory 156 | AppPackages/ 157 | 158 | # Others 159 | *.[Cc]ache 160 | ClientBin/ 161 | [Ss]tyle[Cc]op.* 162 | ~$* 163 | *~ 164 | *.dbmdl 165 | *.dbproj.schemaview 166 | *.pfx 167 | *.publishsettings 168 | node_modules/ 169 | bower_components/ 170 | 171 | # RIA/Silverlight projects 172 | Generated_Code/ 173 | 174 | # Backup & report files from converting an old project file 175 | # to a newer Visual Studio version. Backup files are not needed, 176 | # because we have git ;-) 177 | _UpgradeReport_Files/ 178 | Backup*/ 179 | UpgradeLog*.XML 180 | UpgradeLog*.htm 181 | 182 | # SQL Server files 183 | *.mdf 184 | *.ldf 185 | 186 | # Business Intelligence projects 187 | *.rdl.data 188 | *.bim.layout 189 | *.bim_*.settings 190 | 191 | # Microsoft Fakes 192 | FakesAssemblies/ 193 | 194 | # Node.js Tools for Visual Studio 195 | .ntvs_analysis.dat 196 | 197 | # Visual Studio 6 build log 198 | *.plg 199 | 200 | # Visual Studio 6 workspace options file 201 | *.opt -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | os: 4 | - linux 5 | 6 | before_install: 7 | - sudo add-apt-repository ppa:george-edison55/precise-backports --yes 8 | - sudo apt-get remove -qq cmake cmake-data 9 | - sudo apt-get update -y -qq 10 | - sudo apt-get install cmake cmake-data 11 | 12 | compiler: 13 | - gcc 14 | - clang 15 | 16 | env: 17 | - CONFIGURATION=Debug 18 | - CONFIGURATION=Release 19 | 20 | script: 21 | - mkdir build 22 | - cd build 23 | - cmake -DCMAKE_BUILD_TYPE=$CONFIGURATION ../src 24 | - make 25 | -------------------------------------------------------------------------------- /Build/DirectX.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\ 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(DirectXSDKDir)Include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | d3d9.lib;d3dx9.lib;%(AdditionalDependencies) 15 | 16 | 17 | 18 | 19 | $(DirectXSDKDir)Lib\x86\;%(AdditionalLibraryDirectories) 20 | 21 | 22 | 23 | 24 | $(DirectXSDKDir)Lib\x64\;%(AdditionalLibraryDirectories) 25 | 26 | 27 | 28 | 29 | $(DirectXSDKDir) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Build/DirectXMesh.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ..\..\..\DirectXMesh\DirectXMesh\ 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(DirectXMesh);%(AdditionalIncludeDirectories) 12 | 13 | 14 | DirectXMesh.lib;%(AdditionalDependencies) 15 | 16 | 17 | 18 | 19 | $(DirectXMesh)Bin\Desktop_2015_Win10\$(Platform)\Debug\;%(AdditionalLibraryDirectories) 20 | 21 | 22 | 23 | 24 | $(DirectXMesh)Bin\Desktop_2015_Win10\$(Platform)\Release\;%(AdditionalLibraryDirectories) 25 | 26 | 27 | 28 | 29 | $(DirectXMesh) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Build/VS2012/TootleSample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /Build/VS2012/TootleSampleSoftware.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /Build/VS2013/TootleSample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /Build/VS2013/TootleSampleSoftware.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /Build/VS2015 - DX11_1/Tootle.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TootleLib", "TootleLib.vcxproj", "{F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TootleSample", "TootleSample_DX11_1.vcxproj", "{0F3108B0-4779-4640-8891-1A1E1200A84E}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXMesh", "..\..\..\DirectXMesh\DirectXMesh\DirectXMesh_Desktop_2015_Win10.vcxproj", "{6857F086-F6FE-4150-9ED7-7446F1C1C220}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug_Static_MTDLL|Win32 = Debug_Static_MTDLL|Win32 15 | Debug_Static_MTDLL|x64 = Debug_Static_MTDLL|x64 16 | Debug|Win32 = Debug|Win32 17 | Debug|x64 = Debug|x64 18 | Profile|Win32 = Profile|Win32 19 | Profile|x64 = Profile|x64 20 | Release_Static_MTDLL|Win32 = Release_Static_MTDLL|Win32 21 | Release_Static_MTDLL|x64 = Release_Static_MTDLL|x64 22 | Release|Win32 = Release|Win32 23 | Release|x64 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug_Static_MTDLL|Win32.ActiveCfg = Debug_Static_MTDLL|Win32 27 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug_Static_MTDLL|Win32.Build.0 = Debug_Static_MTDLL|Win32 28 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug_Static_MTDLL|x64.ActiveCfg = Debug_Static_MTDLL|x64 29 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug_Static_MTDLL|x64.Build.0 = Debug_Static_MTDLL|x64 30 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug|Win32.ActiveCfg = Debug_Static_MTDLL|Win32 31 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug|Win32.Build.0 = Debug_Static_MTDLL|Win32 32 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug|x64.ActiveCfg = Debug_Static_MTDLL|x64 33 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Debug|x64.Build.0 = Debug_Static_MTDLL|x64 34 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Profile|Win32.ActiveCfg = Release_Static_MTDLL|Win32 35 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Profile|Win32.Build.0 = Release_Static_MTDLL|Win32 36 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Profile|x64.ActiveCfg = Release_Static_MTDLL|x64 37 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Profile|x64.Build.0 = Release_Static_MTDLL|x64 38 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release_Static_MTDLL|Win32.ActiveCfg = Release_Static_MTDLL|Win32 39 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release_Static_MTDLL|Win32.Build.0 = Release_Static_MTDLL|Win32 40 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release_Static_MTDLL|x64.ActiveCfg = Release_Static_MTDLL|x64 41 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release_Static_MTDLL|x64.Build.0 = Release_Static_MTDLL|x64 42 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release|Win32.ActiveCfg = Release_Static_MTDLL|Win32 43 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release|Win32.Build.0 = Release_Static_MTDLL|Win32 44 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release|x64.ActiveCfg = Release_Static_MTDLL|x64 45 | {F211DAFB-4BD4-4E13-B4FD-9D431D84F4C8}.Release|x64.Build.0 = Release_Static_MTDLL|x64 46 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug_Static_MTDLL|Win32.ActiveCfg = Debug_Static_MTDLL|Win32 47 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug_Static_MTDLL|Win32.Build.0 = Debug_Static_MTDLL|Win32 48 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug_Static_MTDLL|x64.ActiveCfg = Debug_Static_MTDLL|x64 49 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug_Static_MTDLL|x64.Build.0 = Debug_Static_MTDLL|x64 50 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug|Win32.ActiveCfg = Debug_Static_MTDLL|Win32 51 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug|Win32.Build.0 = Debug_Static_MTDLL|Win32 52 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug|x64.ActiveCfg = Debug_Static_MTDLL|x64 53 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Debug|x64.Build.0 = Debug_Static_MTDLL|x64 54 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Profile|Win32.ActiveCfg = Release_Static_MTDLL|Win32 55 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Profile|Win32.Build.0 = Release_Static_MTDLL|Win32 56 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Profile|x64.ActiveCfg = Release_Static_MTDLL|x64 57 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Profile|x64.Build.0 = Release_Static_MTDLL|x64 58 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release_Static_MTDLL|Win32.ActiveCfg = Release_Static_MTDLL|Win32 59 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release_Static_MTDLL|Win32.Build.0 = Release_Static_MTDLL|Win32 60 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release_Static_MTDLL|x64.ActiveCfg = Release_Static_MTDLL|x64 61 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release_Static_MTDLL|x64.Build.0 = Release_Static_MTDLL|x64 62 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release|Win32.ActiveCfg = Release_Static_MTDLL|Win32 63 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release|Win32.Build.0 = Release_Static_MTDLL|Win32 64 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release|x64.ActiveCfg = Release_Static_MTDLL|x64 65 | {0F3108B0-4779-4640-8891-1A1E1200A84E}.Release|x64.Build.0 = Release_Static_MTDLL|x64 66 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug_Static_MTDLL|Win32.ActiveCfg = Debug|Win32 67 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug_Static_MTDLL|Win32.Build.0 = Debug|Win32 68 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug_Static_MTDLL|x64.ActiveCfg = Debug|x64 69 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug_Static_MTDLL|x64.Build.0 = Debug|x64 70 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug|Win32.ActiveCfg = Debug|Win32 71 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug|Win32.Build.0 = Debug|Win32 72 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug|x64.ActiveCfg = Debug|x64 73 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Debug|x64.Build.0 = Debug|x64 74 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Profile|Win32.ActiveCfg = Profile|Win32 75 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Profile|Win32.Build.0 = Profile|Win32 76 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Profile|x64.ActiveCfg = Profile|x64 77 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Profile|x64.Build.0 = Profile|x64 78 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release_Static_MTDLL|Win32.ActiveCfg = Release|Win32 79 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release_Static_MTDLL|Win32.Build.0 = Release|Win32 80 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release_Static_MTDLL|x64.ActiveCfg = Release|x64 81 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release_Static_MTDLL|x64.Build.0 = Release|x64 82 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release|Win32.ActiveCfg = Release|Win32 83 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release|Win32.Build.0 = Release|Win32 84 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release|x64.ActiveCfg = Release|x64 85 | {6857F086-F6FE-4150-9ED7-7446F1C1C220}.Release|x64.Build.0 = Release|x64 86 | EndGlobalSection 87 | GlobalSection(SolutionProperties) = preSolution 88 | HideSolutionNode = FALSE 89 | EndGlobalSection 90 | EndGlobal 91 | -------------------------------------------------------------------------------- /Build/VS2015 - DX11_1/TootleSample_DX11_1.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug_Static_MTDLL 6 | Win32 7 | 8 | 9 | Release_Static_MTDLL 10 | Win32 11 | 12 | 13 | Debug_Static_MTDLL 14 | x64 15 | 16 | 17 | Release_Static_MTDLL 18 | x64 19 | 20 | 21 | 22 | TootleSample 23 | {0F3108B0-4779-4640-8891-1A1E1200A84E} 24 | TootleSample 25 | Win32Proj 26 | 27 | 28 | 29 | Application 30 | v140 31 | MultiByte 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectName) 39 | ..\..\bin\ 40 | obj\$(ProjectName)\$(Configuration)-$(Platform)\ 41 | 42 | 43 | 44 | ..\..\src\TootleLib\include;%(AdditionalIncludeDirectories) 45 | Level3 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | $(OutDir)$(TargetName)$(TargetExt) 53 | ..\..\lib;%(AdditionalLibraryDirectories) 54 | Console 55 | true 56 | $(OutDir)$(TargetName).pdb 57 | true 58 | 59 | 60 | 61 | 62 | Disabled 63 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 64 | MultiThreadedDebugDLL 65 | 66 | 67 | TootleStatic_2015_DX11_1_MTDLL_d.lib;%(AdditionalDependencies) 68 | MachineX86 69 | false 70 | 71 | 72 | 73 | 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | MultiThreadedDLL 76 | 77 | 78 | TootleStatic_2015_DX11_1_MTDLL.lib;%(AdditionalDependencies) 79 | MachineX86 80 | 81 | 82 | 83 | 84 | Disabled 85 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 86 | MultiThreadedDebugDLL 87 | 88 | 89 | TootleStatic_2015_DX11_1_MTDLL_d64.lib;%(AdditionalDependencies) 90 | MachineX64 91 | 92 | 93 | 94 | 95 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 96 | MultiThreadedDLL 97 | 98 | 99 | TootleStatic_2015_DX11_1_MTDLL_64.lib;%(AdditionalDependencies) 100 | MachineX64 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | {f211dafb-4bd4-4e13-b4fd-9d431d84f4c8} 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /Build/VS2015 - DX11_1/TootleSample_DX11_1.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /Build/VS2015/TootleSample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | -------------------------------------------------------------------------------- /Build/VS2015/TootleSampleSoftware.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tootle retirement 2 | 3 | amd-tootle is no longer being actively developed or supported by AMD and is being archived. 4 | 5 | # amd-tootle [![Build status](https://ci.appveyor.com/api/projects/status/t9kao41or7eqp1dg?svg=true)](https://ci.appveyor.com/project/bpurnomo/amd-tootle) [![Build Status](https://travis-ci.org/GPUOpen-Tools/amd-tootle.svg?branch=master)](https://travis-ci.org/GPUOpen-Tools/amd-tootle) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) 6 | The amd-tootle repository includes the source code of the AMD Tootle library and an application command line tool. 7 | 8 | AMD Tootle (Triangle Order Optimization Tool) is a 3D triangle mesh optimization library that improves on existing mesh preprocessing techniques. By using AMD Tootle, developers can optimize their models for pixel overdraw as well as vertex cache performance. This can provide significant performance improvements in pixel limited situations, with no penalty in vertex-limited scenarios, and no runtime cost. 9 | 10 | # AMD Tootle Features 11 | 1. **Vertex cache optimization**: Triangles are re-ordered to optimize for the post-transform vertex cache in modern GPUs. This will yield significant performance improvements in vertex-tranform limited scenes. 12 | 2. **Overdraw optimization**: To reduce the pixel cost of rendering a mesh, the AMD Tootle library further re-orders the triangles in the mesh to reduce pixel overdraw. Significant reductions in pixel overdraw (2x or higher) can be achieved. This can yield significant performance improvements in pixel-limited scenes, and incurs no penalty in vertex-limited scenarios. 13 | 3. **Vertex prefetch cache optimization**: Triangle indices are re-indexed in the order of their occurrence in the triangle list. The vertex buffer is re-ordered to match these new indices. Thus, vertices are accessed close to each other in memory. This optimization exploits the input vertex cache because vertices are typically fetched in a cacheline (that may contains more than one vertex data). 14 | 15 | AMD Tootle supports Microsoft Windows and Linux platform. 16 | 17 | # Package Contents 18 | The amd-tootle package has the following directory structure. 19 | - *bin*: the location for the output AMD Tootle executable and DLL files 20 | - *Build* 21 | - *VS2012*: contains the AMD Tootle solution and project files for Microsoft Visual Studio 2012 22 | - *VS2013*: contains the AMD Tootle solution and project files for Microsoft Visual Studio 2013 23 | - *VS2015*: contains the AMD Tootle solution and project files for Microsoft Visual Studio 2015 24 | - *VS2015 - DX 11.1*: contains the AMD Tootle solution and project files for Microsoft Visual Studio 2015 without DirectX SDK June 2010 dependency (requires DirectXMesh project) 25 | - *DirectX.props*: the Visual Studio property file that points to the location of Microsoft DirectX SDK in the system 26 | * Update this file to point to the location of the Microsoft DirectX SDK in your system (the current support is for Microsoft DirectX SDK June 2010) 27 | - *docs*: contains tootle papers and presentations 28 | - *lib*: the location for the output AMD Tootle static library and import files 29 | - *meshes*: contains several sample meshes 30 | - *src* 31 | - *TootleLib*: contains the source code of the AMD Tootle library that can be linked to your mesh processing pipeline. There are multiple different build targets supported. 32 | - *include/tootlelib.h*: the AMD Tootle library header file 33 | - *TootleSample*: contains the source code of a sample application that reads a single material triangle mesh file *.obj* and exposes the functionality of the AMD Tootle library using a command line interface. 34 | 35 | # Build and Run Steps 36 | 1. Set up Microsoft DirectX SDK dependency (the current support is for Microsoft DirectX SDK June 2010) 37 | * [Install DirectX SDK June 2010](https://www.microsoft.com/en-us/download/details.aspx?id=6812). **To skip this step for Windows 8 and later versions, use VS2015 - DX_11.1 solution file.** 38 | 2. Clone the amd-tootle repository 39 | * `git clone https://github.com/GPUOpen-Tools/amd-tootle.git` 40 | 3. Build the AMD Tootle library and command line tool 41 | * On Windows 42 | * Open *Build/VS2015/Tootle.sln* if working with Microsoft Visual Studio 2015. 43 | * If you want to build without DirectX SDK June 2010, then 44 | * Run `python Scripts/FetchDependencies.py` 45 | * Open *Build/VS2015 - DX11_1/Tootle.sln* instead 46 | * Select the appropriate build target for AMD Tootle within Microsoft Visual Studio 47 | * Build all the projects 48 | * The output files will be generated in the *bin* and *lib* folder 49 | * A *runTest.bat* batch file is provided in the *bin* folder as an example for running the Tootle command line tool (*TootleSample.exe*) 50 | * On a Windows console window, you can run *TootleSample.exe* without any command line arguments to print the instruction for running the tool 51 | * On Linux 52 | * Build the AMD Tootle library 53 | * `cd src/TootleLib` 54 | * `make` 55 | * Build the AMD Tootle command line tool 56 | * `cd ../TootleSample` 57 | * `make` 58 | * Run the AMD Tootle command line tool 59 | * `cd ../../bin` 60 | * `./TootleSample -a 5 ../meshes/bolt.obj > out.obj` 61 | * You can run `./TootleSample` without any command line arguments to print the instruction for running the tool 62 | 63 | # References 64 | 1. Nehab, D. Barczak, J. Sander, P.V. 2006. Triangle Order Optimization for graphics hardware computation culling. In Proceedings of the ACM SIGGRAPH Symposium on Interactive 3D Graphics and Games, pages 207-211 65 | 2. Sander, P.V., Nehab, D. Barczak, J. 2007. Fast Triangle Reordering for Vertex Locality and Reduced Overdraw. ACM Transactions of Graphics (Proc. SIGGRAPH), 26(3), August 2007. 66 | -------------------------------------------------------------------------------- /Scripts/FetchDependencies.py: -------------------------------------------------------------------------------- 1 | #!python 2 | import os 3 | import string 4 | import subprocess 5 | 6 | # to allow the script to be run from anywhere - not just the cwd - store the absolute path to the script file 7 | scriptRoot = os.path.dirname(os.path.realpath(__file__)) 8 | 9 | # Update or clone a project folder 10 | def gitclone(gitPath, tagValue, targetRelativePath): 11 | # convert projectValue to OS specific format 12 | tmppath = os.path.join(scriptRoot, targetRelativePath) 13 | # clean up path, collapsing any ../ and converting / to \ for Windows 14 | targetPath = os.path.normpath(tmppath) 15 | print("\n\nProcessing project %s"%targetPath) 16 | if os.path.isdir(targetPath): 17 | print("\nDirectory " + targetPath + " exists") 18 | else: 19 | print("\nDirectory " + targetPath + " does not exist, using 'git clone' to get latest based on tag %s"%tagValue) 20 | commandArgs = ["git", "clone", gitPath, targetPath] 21 | p = subprocess.Popen( commandArgs ) 22 | p.wait() 23 | p = subprocess.Popen(["git", "checkout", "tags/" + tagValue], cwd=targetPath) 24 | p.wait(); 25 | 26 | if __name__ == "__main__": 27 | 28 | gitclone("https://github.com/Microsoft/DirectXMesh.git", "apr2017", "../../DirectXMesh") 29 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - GENERATOR: "Visual Studio 11 2012" 4 | CONFIG: Debug 5 | 6 | - GENERATOR: "Visual Studio 11 2012" 7 | CONFIG: Release 8 | 9 | - GENERATOR: "Visual Studio 11 2012 Win64" 10 | CONFIG: Debug 11 | 12 | - GENERATOR: "Visual Studio 11 2012 Win64" 13 | CONFIG: Release 14 | 15 | - GENERATOR: "Visual Studio 12 2013" 16 | CONFIG: Debug 17 | 18 | - GENERATOR: "Visual Studio 12 2013" 19 | CONFIG: Release 20 | 21 | - GENERATOR: "Visual Studio 12 2013 Win64" 22 | CONFIG: Debug 23 | 24 | - GENERATOR: "Visual Studio 12 2013 Win64" 25 | CONFIG: Release 26 | 27 | - GENERATOR: "Visual Studio 14 2015" 28 | CONFIG: Debug 29 | 30 | - GENERATOR: "Visual Studio 14 2015" 31 | CONFIG: Release 32 | 33 | - GENERATOR: "Visual Studio 14 2015 Win64" 34 | CONFIG: Debug 35 | 36 | - GENERATOR: "Visual Studio 14 2015 Win64" 37 | CONFIG: Release 38 | 39 | build_script: 40 | - mkdir _cibuild 41 | - cd _cibuild 42 | - cmake "-G%GENERATOR%" ../src 43 | - cmake --build . --config "%CONFIG%" 44 | -------------------------------------------------------------------------------- /bin/runTest.bat: -------------------------------------------------------------------------------- 1 | TootleSample.exe -a 5 ..\meshes\bolt.obj > out.obj 2 | 3 | PAUSE 4 | -------------------------------------------------------------------------------- /docs/tootle-i3d2006-paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GPUOpen-Archive/amd_tootle/74cbd6b33e75ef90a9c395772850992ef29cd7fe/docs/tootle-i3d2006-paper.pdf -------------------------------------------------------------------------------- /docs/tootle-i3d2006-talk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GPUOpen-Archive/amd_tootle/74cbd6b33e75ef90a9c395772850992ef29cd7fe/docs/tootle-i3d2006-talk.pdf -------------------------------------------------------------------------------- /docs/tootle2-siggraph2007-paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GPUOpen-Archive/amd_tootle/74cbd6b33e75ef90a9c395772850992ef29cd7fe/docs/tootle2-siggraph2007-paper.pdf -------------------------------------------------------------------------------- /docs/tootle2-siggraph2007-talk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GPUOpen-Archive/amd_tootle/74cbd6b33e75ef90a9c395772850992ef29cd7fe/docs/tootle2-siggraph2007-talk.pdf -------------------------------------------------------------------------------- /lib/EMPTY.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GPUOpen-Archive/amd_tootle/74cbd6b33e75ef90a9c395772850992ef29cd7fe/lib/EMPTY.txt -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.1) 2 | PROJECT(AMD_TOOTLE) 3 | SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON) 4 | ENABLE_TESTING() 5 | 6 | ADD_SUBDIRECTORY(TootleLib) 7 | ADD_SUBDIRECTORY(TootleSample) 8 | -------------------------------------------------------------------------------- /src/TootleLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(TootleLib) 2 | 3 | SET(SOURCES 4 | aligned_malloc.cpp 5 | clustering.cpp 6 | error.c 7 | feedback.cpp 8 | fit.cpp 9 | heap.c 10 | overdraw.cpp 11 | soup.cpp 12 | souptomesh.cpp 13 | Stripifier.cpp 14 | Timer.cpp 15 | tootlelib.cpp 16 | triorder.cpp 17 | 18 | RayTracer/TootleRaytracer.cpp 19 | RayTracer/JRT/JRTBoundingBox.cpp 20 | RayTracer/JRT/JRTCamera.cpp 21 | RayTracer/JRT/JRTCore.cpp 22 | RayTracer/JRT/JRTCoreUtils.cpp 23 | RayTracer/JRT/JRTH2KDTreeBuilder.cpp 24 | RayTracer/JRT/JRTHeuristicKDTreeBuilder.cpp 25 | RayTracer/JRT/JRTKDTree.cpp 26 | RayTracer/JRT/JRTKDTreeBuilder.cpp 27 | RayTracer/JRT/JRTMesh.cpp 28 | RayTracer/JRT/JRTOrthoCamera.cpp 29 | RayTracer/JRT/JRTPPMImage.cpp 30 | RayTracer/JRT/JRTTriangleIntersection.cpp 31 | RayTracer/Math/JMLFuncs.cpp) 32 | 33 | SET(HEADERS 34 | aligned_malloc.h 35 | bbox.h 36 | cloud.h 37 | clustering.h 38 | color.h 39 | error.h 40 | feedback.h 41 | fit.h 42 | heap.h 43 | matrix.h 44 | mesh.h 45 | option.h 46 | overdraw.h 47 | quaternion.h 48 | scalar.h 49 | soup.h 50 | souptomesh.h 51 | Stripifier.h 52 | Timer.h 53 | TootlePCH.h 54 | triorder.h 55 | vector.h 56 | viewpoints.h 57 | window.h 58 | 59 | include/tootlelib.h 60 | 61 | RayTracer/TootleRaytracer.h 62 | RayTracer/JRT/JRTBoundingBox.h 63 | RayTracer/JRT/JRTCamera.h 64 | RayTracer/JRT/JRTCommon.h 65 | RayTracer/JRT/JRTCore.h 66 | RayTracer/JRT/JRTCoreUtils.h 67 | RayTracer/JRT/JRTH2KDTreeBuilder.h 68 | RayTracer/JRT/JRTHeuristicKDTreeBuilder.h 69 | RayTracer/JRT/JRTKDTree.h 70 | RayTracer/JRT/JRTKDTreeBuilder.h 71 | RayTracer/JRT/JRTMesh.h 72 | RayTracer/JRT/JRTOrthoCamera.h 73 | RayTracer/JRT/JRTPPMImage.h 74 | RayTracer/JRT/JRTTriangleIntersection.h 75 | RayTracer/Math/JML.h 76 | RayTracer/Math/JMLFuncs.h 77 | RayTracer/Math/JMLMatrix.h 78 | RayTracer/Math/JMLScalar.h 79 | RayTracer/Math/JMLSSEVec.h 80 | RayTracer/Math/JMLVec2.h 81 | RayTracer/Math/JMLVec3.h) 82 | 83 | ADD_LIBRARY(TootleLib STATIC ${SOURCES} ${HEADERS}) 84 | TARGET_INCLUDE_DIRECTORIES(TootleLib 85 | PUBLIC include 86 | PRIVATE 87 | RayTracer/JRT 88 | RayTracer/Math 89 | RayTracer 90 | ${CMAKE_CURRENT_SOURCE_DIR}) 91 | 92 | TARGET_COMPILE_DEFINITIONS(TootleLib 93 | PUBLIC _SOFTWARE_ONLY_VERSION) 94 | 95 | IF(UNIX) 96 | TARGET_COMPILE_DEFINITIONS(TootleLib 97 | PUBLIC _LINUX) 98 | 99 | SET_PROPERTY(TARGET TootleLib PROPERTY CXX_STANDARD 11) 100 | SET_PROPERTY(TARGET TootleLib PROPERTY CXX_STANDARD_REQUIRED ON) 101 | ENDIF() 102 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTBoundingBox.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _FRT_BOUNDING_BOX_H_ 7 | #define _FRT_BOUNDING_BOX_H_ 8 | 9 | #include "JMLSSEVec.h" 10 | 11 | typedef SSEVec4 SSEVector; 12 | 13 | class JRTBoundingBox 14 | { 15 | public: 16 | 17 | JRTBoundingBox(const float* points, unsigned int num_points); 18 | 19 | JRTBoundingBox(const Vec3f* points, unsigned int num_points); 20 | 21 | JRTBoundingBox(const Vec3f& min = Vec3f(0, 0, 0), const Vec3f& max = Vec3f(1, 1, 1)); 22 | 23 | inline const Vec3f& GetMin() const { return m_min; }; 24 | inline const Vec3f& GetMax() const { return m_max; }; 25 | 26 | inline Vec3f& GetMin() { return m_min; }; 27 | inline Vec3f& GetMax() { return m_max; }; 28 | 29 | Vec3f GetCenter() const { return (m_max + m_min) / 2 ; }; 30 | 31 | void Expand(const Vec3f& point); 32 | 33 | bool RayHit(const Vec3f& origin, const Vec3f& endPoint, float* tmin_out, float* tmax_out) const; 34 | 35 | 36 | void Split(unsigned int axis, float value, JRTBoundingBox& front, JRTBoundingBox& back) const; 37 | 38 | 39 | bool PointInBox(const float origin[3]) const; 40 | 41 | JRTBoundingBox Union(const JRTBoundingBox& rOther) const; 42 | 43 | /// Checks for intersection between this box and another, and optionally returns the intersection 44 | /// \param rOther 45 | /// The other box to test for intersection with 46 | /// \param pBBOut 47 | /// Pointer to receive a bounding box containing the intersection of the two boxes 48 | /// \return True if the boxes intersect, false if not 49 | bool Intersection(const JRTBoundingBox& rOther, JRTBoundingBox* pBBOut) const; 50 | 51 | float GetVolume() const; 52 | 53 | float GetSurfaceArea() const; 54 | 55 | bool TriangleIntersect(const Vec3f* pV1, const Vec3f* pV2, const Vec3f* pV3) const; 56 | 57 | bool IsDegenerate() const; 58 | 59 | void GetCorners(Vec3f* pCorners) const; 60 | 61 | private: 62 | 63 | Vec3f m_min; 64 | Vec3f m_max; 65 | }; 66 | 67 | JRTBoundingBox JRTBBoxUnion(const JRTBoundingBox& rFirst, const JRTBoundingBox& rSecond); 68 | JRTBoundingBox JRTBBoxIntersection(const JRTBoundingBox& rFirst, const JRTBoundingBox& rSecond); 69 | JRTBoundingBox JRTBBoxDifference(const JRTBoundingBox& rFirst, const JRTBoundingBox& rSecond); 70 | 71 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCamera.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include "JRTCommon.h" 8 | #include "JRTCamera.h" 9 | 10 | 11 | /// \param position 12 | /// Camera position 13 | /// \param direction 14 | /// Camera direction 15 | /// \param up 16 | /// The 'up' vector 17 | /// \param fov 18 | /// Field of view angle, in radians 19 | 20 | JRTPerspectiveCamera::JRTPerspectiveCamera(const Vec3f& position, const Vec3f& direction, const Vec3f& up, float fov) 21 | : m_position(position), 22 | m_direction(direction) 23 | { 24 | m_right = Cross(up, direction); 25 | m_up = Cross(direction, m_right); 26 | 27 | m_right = Normalize(m_right); 28 | m_up = Normalize(m_up); 29 | 30 | // distance from center of viewing plane to edges 31 | // assuming a hither distance of 1, it is: tan(fov/2.0) 32 | // draw a diagram if you're curious 33 | m_plane_width = tan(fov / 2.0f); 34 | 35 | 36 | Vec3f H = m_right * m_plane_width; 37 | Vec3f V = m_up * m_plane_width; 38 | Vec3f center = m_position + m_direction; 39 | 40 | // get the pixel center on the top-left corner of the image plane 41 | m_corner = center - H; 42 | m_corner = m_corner + V; 43 | 44 | m_plane_width *= 2.0; 45 | m_aspect = 1; 46 | } 47 | 48 | 49 | void JRTPerspectiveCamera::SetAspectRatio(float aspect) 50 | { 51 | // recompute 'corner' position for sampling 52 | Vec3f center = m_position + m_direction; 53 | Vec3f H = m_right * (m_plane_width / 2.0f) * aspect; 54 | Vec3f V = m_up * (m_plane_width / 2.0f); 55 | 56 | m_corner = center - H; 57 | m_corner = m_corner + V; 58 | m_aspect = aspect; 59 | } 60 | 61 | void JRTPerspectiveCamera::GetRay(float s, float t, Vec3f* origin, Vec3f* delta) const 62 | { 63 | // correct for aspect ratio 64 | s *= m_aspect; 65 | 66 | s *= m_plane_width; 67 | t *= m_plane_width; 68 | Vec3f pixel_center = m_corner + (m_right * s) + (m_up * -t); 69 | Vec3f dir = (pixel_center - m_position); 70 | 71 | *origin = m_position; 72 | *delta = dir; 73 | 74 | } 75 | 76 | 77 | void JRTPerspectiveCamera::ProjectPoint(const Vec3f& pt, float* s, float* t) const 78 | { 79 | // convert point to camera space 80 | Vec3f pcam = pt - m_position; 81 | Vec3f camera_space_pt = (m_right * pcam.x) + (m_up * pcam.y) + (m_direction * pcam.z); 82 | 83 | if (camera_space_pt.z <= 0.0) 84 | { 85 | *s = -1; 86 | *t = -1; 87 | return; 88 | } 89 | 90 | // splat point onto image plane and find out where it lands 91 | // we are looking for a vector such that z=1 92 | float val = 1.0f / camera_space_pt.z; 93 | Vec3f splat; 94 | splat.x = val * camera_space_pt.x; 95 | splat.y = val * camera_space_pt.y; 96 | splat.z = 1; 97 | 98 | // normalize to size of image plane and clip 99 | splat.x /= m_plane_width; 100 | splat.y /= -m_plane_width; 101 | 102 | if (std::abs(splat.x) > 0.5 || std::abs(splat.y) > 0.5) 103 | { 104 | *s = -1; 105 | *t = -1; 106 | return; 107 | } 108 | 109 | // correct for aspect ratio and convert to NDC space 110 | splat.x /= m_aspect; 111 | splat.x += 0.5; 112 | splat.y += 0.5; 113 | *s = splat.x; 114 | *t = splat.y; 115 | 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCamera.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_CAMERA_H_ 7 | #define _JRT_CAMERA_H_ 8 | 9 | #include "JRTCommon.h" 10 | 11 | 12 | class JRTCamera 13 | { 14 | public: 15 | virtual ~JRTCamera() {}; 16 | virtual void GetRay(float s, float t, Vec3f* origin, Vec3f* delta) const = 0; 17 | virtual void SetAspectRatio(float aspect) = 0; 18 | 19 | // returns the position of the given point in camera NDC space 20 | // if the point is not visible, s and t are each set to -1 21 | virtual void ProjectPoint(const Vec3f& pt, float* s, float* t) const = 0; 22 | }; 23 | 24 | 25 | class JRTPerspectiveCamera : virtual public JRTCamera 26 | { 27 | public: 28 | JRTPerspectiveCamera(const Vec3f& position, const Vec3f& direction, const Vec3f& up, float fov = 3.1415926); 29 | 30 | virtual void GetRay(float s, float t, Vec3f* origin, Vec3f* delta) const ; 31 | virtual void SetAspectRatio(float aspect) ; 32 | 33 | // returns the position of the given point in camera NDC space 34 | // if the point is not visible, s and t are each set to -1 35 | virtual void ProjectPoint(const Vec3f& pt, float* s, float* t) const ; 36 | 37 | private: 38 | float m_aspect; 39 | Vec3f m_position; // eye position in world space 40 | Vec3f m_direction; // viewing axis in world space 41 | Vec3f m_up; // "true" up. Vertical direction in world-space image plane 42 | Vec3f m_right; // horizontal direction in world-space image plane 43 | 44 | float m_plane_width; // size of image plane 45 | Vec3f m_corner; // top-left corner of image plane - world space 46 | 47 | }; 48 | 49 | 50 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCommon.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_COMMON_H_ 7 | #define _JRT_COMMON_H_ 8 | 9 | /// epsilon value used in intersection computations. 10 | #define JRTEPSILON 0.00001f 11 | 12 | #include "TootlePCH.h" 13 | 14 | #include 15 | 16 | #ifdef _LINUX 17 | typedef unsigned long long UINT64; 18 | #else 19 | typedef unsigned __int64 UINT64; 20 | #endif 21 | typedef unsigned int UINT; 22 | typedef unsigned short USHORT; 23 | typedef unsigned char UBYTE; 24 | 25 | #include "JML.h" 26 | using namespace JML; 27 | 28 | #define JRT_ASSERT(x) assert(x) 29 | #define JRT_SAFE_DELETE(x) {if(x) delete x; x = NULL;} 30 | #define JRT_SAFE_DELETE_ARRAY(x) { if(x) delete[] x; x=NULL; } 31 | 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCore.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include "JRTCommon.h" 8 | #include "JRTCore.h" 9 | #include "JRTMesh.h" 10 | 11 | #include "JRTKDTree.h" 12 | #include "JRTKDTreeBuilder.h" 13 | #include "JRTHeuristicKDTreeBuilder.h" 14 | #include "JRTH2KDTreeBuilder.h" 15 | 16 | 17 | JRTCore::JRTCore() : m_pTree(NULL), m_pHitArray(new TootleRayHit[5]), m_nArraySize(5) 18 | { 19 | 20 | } 21 | 22 | JRTCore::~JRTCore() 23 | { 24 | JRT_SAFE_DELETE(m_pTree); 25 | JRT_SAFE_DELETE_ARRAY(m_pHitArray); 26 | } 27 | 28 | 29 | JRTCore* JRTCore::Build(const std::vector& rMeshes) 30 | { 31 | JRTCore* pCaster = new JRTCore(); 32 | 33 | if (rMeshes.size() == 0) 34 | { 35 | pCaster->m_pTree = NULL; 36 | return pCaster; 37 | } 38 | 39 | // build KD tree 40 | JRTHeuristicKDTreeBuilder builder; 41 | JRTKDTree* pTree = builder.BuildTree(rMeshes); 42 | 43 | if (!pTree) 44 | { 45 | delete pCaster; 46 | return NULL; 47 | } 48 | 49 | pCaster->m_pTree = pTree; 50 | 51 | return pCaster; 52 | } 53 | 54 | 55 | int SortTootleHit(const void* h1, const void* h2) 56 | { 57 | const TootleRayHit* ph1 = (const TootleRayHit*) h1; 58 | const TootleRayHit* ph2 = (const TootleRayHit*) h2; 59 | return ph1->t >= ph2->t; 60 | } 61 | 62 | 63 | /// \param rOrigin The ray origin 64 | /// \param rDirection The ray direction 65 | /// \param ppHitArray A pointer that will be set to point to an array of hits. The caller should NOT delete the returned array 66 | /// \param pHitCount A pointer that will receive the number of hits in the returned array. 67 | /// \return Returns false if out of memory, true otherwise. 68 | bool JRTCore::FindAllHits(const Vec3f& rOrigin, const Vec3f& rDirection, TootleRayHit** ppHitArray, UINT* pHitCount) 69 | { 70 | if (!m_pTree) 71 | { 72 | *ppHitArray = NULL; 73 | *pHitCount = 0; 74 | } 75 | 76 | UINT nHits = m_pTree->FindAllHits(rOrigin, rDirection, &m_pHitArray, &m_nArraySize); 77 | 78 | if (nHits == 0 || nHits == JRTKDTree::OUT_OF_MEMORY) 79 | { 80 | *ppHitArray = NULL; 81 | *pHitCount = 0; 82 | } 83 | 84 | if (nHits == JRTKDTree::OUT_OF_MEMORY) 85 | { 86 | return false; 87 | } 88 | 89 | #ifdef DEBUG 90 | 91 | // verify that there are no duplicates, just a test 92 | for (UINT i = 0; i < nHits; i++) 93 | { 94 | for (UINT j = i + 1; j < nHits; j++) 95 | { 96 | JRT_ASSERT(m_pHitArray[i].nFaceID != m_pHitArray[j].nFaceID) 97 | } 98 | } 99 | 100 | #endif 101 | 102 | // sort hits by distance 103 | qsort(m_pHitArray, nHits, sizeof(TootleRayHit), &SortTootleHit); 104 | *ppHitArray = m_pHitArray; 105 | *pHitCount = nHits; 106 | 107 | return true; 108 | } 109 | 110 | void JRTCore::CullBackfaces(const Vec3f& rViewDir, bool bCullCCW) 111 | { 112 | m_pTree->CullBackfaces(rViewDir, bCullCCW); 113 | } 114 | 115 | 116 | 117 | bool JRTCore::GetSceneBBHit(const Vec3f& rOrigin, const Vec3f& rDirection, Vec3f* pHitPt) 118 | { 119 | const JRTBoundingBox& rBB = m_pTree->GetSceneBounds(); 120 | float fTMin, fTMax; 121 | 122 | if (!rBB.RayHit(rOrigin, rDirection, &fTMin, &fTMax)) 123 | { 124 | return false; 125 | } 126 | 127 | if (fTMax < 0.0f) 128 | { 129 | return false; 130 | } 131 | 132 | *pHitPt = rOrigin + rDirection * fTMax; 133 | return true; 134 | } 135 | 136 | 137 | const JRTBoundingBox& JRTCore::GetSceneBB() const 138 | { 139 | return m_pTree->GetSceneBounds(); 140 | } 141 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCore.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_CORE_H_ 7 | #define _JRT_CORE_H_ 8 | 9 | #include "JRTCommon.h" 10 | #include "JRTTriangleIntersection.h" 11 | 12 | struct JRTHitInfo 13 | { 14 | // the triangle that was hit 15 | const JRTMesh* pMesh; 16 | UINT nIndex; 17 | 18 | Vec3f mPosition; 19 | Vec3f mNormal; 20 | }; 21 | 22 | struct TootleRayHit 23 | { 24 | float t; 25 | UINT nFaceID; 26 | }; 27 | 28 | class JRTCSGNode; 29 | class JRTMesh; 30 | class JRTKDTree; 31 | class JRTBoundingBox; 32 | 33 | class JRTCore 34 | { 35 | public: 36 | 37 | static JRTCore* Build(const std::vector& rPrims); 38 | 39 | ~JRTCore(); 40 | 41 | bool FindAllHits(const Vec3f& rOrigin, const Vec3f& rDirection, TootleRayHit** ppHitArray, UINT* pnHits); 42 | 43 | void CullBackfaces(const Vec3f& rViewDir, bool bCullCCW); 44 | 45 | /// Locates the position at which the given ray hits the scene bounding box. 46 | /// Returns false if the ray misses the bounding box 47 | bool GetSceneBBHit(const Vec3f& rOrigin, const Vec3f& rDirection, Vec3f* pHitPt); 48 | 49 | const JRTBoundingBox& GetSceneBB() const ; 50 | 51 | private: 52 | 53 | JRTCore(); 54 | 55 | TootleRayHit* m_pHitArray; 56 | UINT m_nArraySize; 57 | 58 | JRTKDTree* m_pTree; 59 | }; 60 | 61 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCoreUtils.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include "JRTCommon.h" 8 | #include "JRTCoreUtils.h" 9 | #include "JRTMesh.h" 10 | 11 | 12 | // These arrays are used to implement the UCOMP, VCOMP, WCOMP macros 13 | 14 | // coordinate to drop: X Y Z 15 | const int INDEX1[3] = { 1, 0, 0 }; // projection coord 1 16 | const int INDEX2[3] = { 2, 2, 1 }; // projection coord 2 17 | // projection plane: YZ XZ XY 18 | 19 | TriPlaneState TriPlaneTest(const JRTTriangle& tri, Axis split_component, float split_value) 20 | { 21 | bool front = false, back = false; 22 | 23 | if (tri.GetV1()[split_component] < split_value) 24 | { 25 | back = true; 26 | } 27 | else 28 | { 29 | front = true; 30 | } 31 | 32 | if (tri.GetV2()[split_component] < split_value) 33 | { 34 | back = true; 35 | } 36 | else 37 | { 38 | front = true; 39 | } 40 | 41 | if (tri.GetV3()[split_component] < split_value) 42 | { 43 | back = true; 44 | } 45 | else 46 | { 47 | front = true; 48 | } 49 | 50 | 51 | if (front && back) 52 | { 53 | return STRADDLE; 54 | } 55 | else if (front) 56 | { 57 | return IN_FRONT; 58 | } 59 | else 60 | { 61 | return IN_BACK; 62 | } 63 | } -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTCoreUtils.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_CORE_UTILS_H_ 7 | #define _JRT_CORE_UTILS_H_ 8 | 9 | enum Axis 10 | { 11 | X_AXIS = 0, 12 | Y_AXIS = 1, 13 | Z_AXIS = 2 14 | }; 15 | 16 | inline void SWAP(float& a, float& b) { float tmp = a; a = b; b = tmp; }; 17 | 18 | 19 | // macros for projecting points onto axis-aligned planes 20 | #define UCOMP(P, axis) P[ INDEX1[axis] ] 21 | #define VCOMP(P, axis) P[ INDEX2[axis] ] 22 | #define WCOMP(P, axis) P[ axis ]; 23 | 24 | #define UCOMPINDEX(axis) INDEX1[axis]; 25 | #define VCOMPINDEX(axis) INDEX2[axis]; 26 | #define WCOMPINDEX(axis) axis; 27 | 28 | // these arrays define which coordinates to select when projecting into a plane aligned to a particular axis 29 | extern const int INDEX1[3]; 30 | extern const int INDEX2[3]; 31 | 32 | // 33 | // TriPlaneTest 34 | // Returns a value indicating whether a triangle is in front of, 35 | // behind, or crossing an axis-aligned split plane 36 | // 37 | enum TriPlaneState 38 | { 39 | IN_FRONT, 40 | IN_BACK, 41 | STRADDLE 42 | }; 43 | 44 | class JRTTriangle; 45 | 46 | TriPlaneState TriPlaneTest(const JRTTriangle& tri, Axis split_component, float split_value); 47 | 48 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTH2KDTreeBuilder.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_H2_KDTREE_BUILDER_H_ 7 | #define _JRT_H2_KDTREE_BUILDER_H_ 8 | 9 | #include "JRTCoreUtils.h" 10 | #include "JRTKDTreeBuilder.h" 11 | 12 | /// The H2 KDTree builder is a simplified heuristic tree builder 13 | /// The algorithm works thusly: 14 | /// - for each axis 15 | /// - Start at spatial median, classify polys 16 | /// - If all polys on one side, shift split plane 17 | /// - Choose axis with lowest spatial median cost (using SAH) 18 | 19 | class JRTH2KDTreeBuilder : public JRTKDTreeBuilder 20 | { 21 | public: 22 | 23 | void BuildTreeImpl(const JRTBoundingBox& rBounds, 24 | const std::vector& rTris, 25 | std::vector& rNodesOut, 26 | std::vector& rTriIndicesOut); 27 | 28 | private: 29 | 30 | struct SplitInfo 31 | { 32 | Axis eAxis; 33 | float fHeuristicValue; ///< Estimated cost of this split. If 0, it means do not split 34 | float fPosition; 35 | std::vector TrisFront; 36 | std::vector TrisBack; 37 | }; 38 | 39 | void MakeLeaf(JRTKDNode* pNode, 40 | const std::vector& rTrisThisNode, 41 | std::vector& rNodesOut, 42 | std::vector& rTriIndicesOut); 43 | 44 | void DoBuildTree(UINT nMaxDepth, 45 | JRTKDNode* pNode, 46 | const JRTBoundingBox& rBounds, 47 | const std::vector& rTris, 48 | std::vector& rTrisThisNode, 49 | std::vector& rNodesOut, 50 | std::vector& rTriIndicesOut); 51 | 52 | 53 | void FindBestSplit(Axis eAxis, 54 | const JRTBoundingBox& rBounds, 55 | const std::vector& rTris, 56 | const std::vector& rTrisThisNode, 57 | SplitInfo* pSplitOut); 58 | 59 | void ClassifyTris(Axis eAxis, 60 | float fPosition, 61 | std::vector& rTrisBack, 62 | std::vector& rTrisFront, 63 | UINT& nStraddle, 64 | float& fTriMin, 65 | float& fTriMax, 66 | const std::vector& rTrisThisNode); 67 | 68 | float CostFunction(const JRTBoundingBox& rBounds, SplitInfo* pSlitOut); 69 | 70 | // triangle bounding boxes,used to speed classification 71 | // these are arranged by axis so that they'll cache better 72 | typedef std::pair FloatPair; 73 | std::vector m_BBX; 74 | std::vector m_BBY; 75 | std::vector m_BBZ; 76 | }; 77 | 78 | 79 | 80 | 81 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTHeuristicKDTreeBuilder.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_HEURISTIC_KD_TREE_BUILDER_H_ 7 | #define _JRT_HEURISTIC_KD_TREE_BUILDER_H_ 8 | 9 | 10 | #include "JRTKDTreeBuilder.h" 11 | #include "JRTBoundingBox.h" 12 | #include "JRTCoreUtils.h" 13 | 14 | /// \brief A smart KD tree builder which uses the surface area heuristic 15 | /// Most of the inspiration for this code comes from Havran's PhD thesis 16 | class JRTHeuristicKDTreeBuilder : public JRTKDTreeBuilder 17 | { 18 | public: 19 | 20 | 21 | 22 | struct TriangleBB 23 | { 24 | const JRTTriangle* pTri; 25 | UINT nIndex; 26 | JRTBoundingBox box; 27 | 28 | // state flag used to classify this BB with respect to current partitioning plane 29 | mutable TriPlaneState planeState; 30 | 31 | }; 32 | 33 | 34 | struct Split 35 | { 36 | float value; 37 | unsigned bMaxSplit : 1; 38 | unsigned nTriBB : 31; 39 | 40 | //bool bMaxSplit; /// Is this a max split (end of BB) or a min split (beginning of BB) 41 | //const TriangleBB* pTriBB; 42 | }; 43 | 44 | typedef std::vector SplitVec; 45 | 46 | 47 | protected: 48 | 49 | virtual void BuildTreeImpl(const JRTBoundingBox& rBounds, 50 | const std::vector& rTris, 51 | std::vector& rNodesOut, 52 | std::vector& rTriIndicesOut); 53 | 54 | 55 | private: 56 | 57 | /* void BuildTreeRecursive( UINT nDepth, 58 | const JRTBoundingBox& rNodeBounds, 59 | const std::vector rBBs[3], 60 | JRTKDNode* pNode, 61 | std::vector& rNodesOut, 62 | std::vector& rTriIndicesOut );*/ 63 | 64 | void ExtractSplits(UINT eAxis, const std::vector& rBBs, std::vector& rSplits, const JRTBoundingBox& rSceneBounds); 65 | 66 | void ClassifyBBs(SplitVec& rSplits, std::vector& rBBs, UINT eAxis, float fValue); 67 | 68 | void LocateBestSplit(float fNodeBBInvArea, 69 | const JRTBoundingBox& rNodeBounds, 70 | const SplitVec splits[3], 71 | UINT eAxis, UINT nTriCount, float& fBestCost, bool& bSplit, UINT& eSplitAxis, float& fSplitValue); 72 | 73 | 74 | void BuildTreeRecursive(UINT nDepth, 75 | const JRTBoundingBox& rNodeBounds, 76 | SplitVec splits[3], 77 | std::vector& rBBsThisNode, 78 | JRTKDNode* pNode, 79 | std::vector& rNodesOut, 80 | std::vector& rTriIndicesOut); 81 | 82 | JRTBoundingBox m_scene_bounds; 83 | 84 | 85 | std::vector m_bbs; 86 | 87 | }; 88 | 89 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTKDTree.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_KDTREE_H_ 7 | #define _JRT_KDTREE_H_ 8 | 9 | #include "JRTCommon.h" 10 | #include "JRTBoundingBox.h" 11 | #include "JRTTriangleIntersection.h" 12 | #include "JRTCore.h" 13 | 14 | #ifdef _LINUX 15 | #include "../aligned_malloc.h" 16 | #define _aligned_malloc aligned_malloc 17 | #define _aligned_free aligned_free 18 | #endif 19 | 20 | // *********************************************************** 21 | // Node Data Structure 22 | // *********************************************************** 23 | 24 | // the #pragma pack(1) is so that VC++ will make this structure 8 bytes wide 25 | // if you omit the pack(), VC++ will pad the internal structs and throw the size off 26 | #pragma pack(1) 27 | class JRTKDNode 28 | { 29 | public: 30 | 31 | inline bool IsLeaf() const { return (inner.is_leaf == 1); }; 32 | 33 | 34 | union 35 | { 36 | struct 37 | { 38 | // if an inner node, use this one 39 | unsigned is_leaf : 1; 40 | unsigned axis : 3; 41 | unsigned front_offset : 28; 42 | 43 | float position; // position of splitting plane 44 | 45 | } inner; 46 | 47 | struct 48 | { 49 | // if a leaf, use this one 50 | unsigned is_leaf : 1; 51 | unsigned triangle_start : 31; // offset of first triangle in triangle list 52 | UINT triangle_count;// number of triangles in this node 53 | 54 | } leaf; 55 | }; 56 | 57 | }; 58 | #pragma pack() 59 | 60 | 61 | 62 | 63 | class JRTKDTree 64 | { 65 | public: 66 | 67 | static const UINT MAX_TREE_DEPTH; 68 | 69 | /// Overloaded new operator allocates 16-byte aligned objects using _aligned_malloc 70 | void* operator new(size_t nSize) { return _aligned_malloc(nSize, 16); }; 71 | 72 | /// Overloaded delete operator uses _aligned_free() 73 | void operator delete(void* pObj) { _aligned_free(pObj); }; 74 | 75 | 76 | ~JRTKDTree(); 77 | 78 | bool FindFirstHit(const Vec3f& rOrigin, const Vec3f& rDirection, JRTHitInfo* pHit, const JRTMesh* pExcludeMesh, UINT nExcludeTri, bool* pCSGStates) ; 79 | 80 | void CullBackfaces(const Vec3f& rViewDir, bool bCullCCW); 81 | 82 | UINT FindAllHits(const Vec3f& rOrigin, const Vec3f& rDirection, TootleRayHit** ppHitArray, UINT* pnArraySize); 83 | 84 | UINT GetNodeCount() const { return m_nNodeCount; }; 85 | 86 | /// Returns total number of tris in tree (not taking into account duplication) 87 | UINT GetTriCount() const { return m_nTriangleCount; }; 88 | 89 | /// Returns total number of triangle references for all leaves 90 | UINT GetIndexCount() const { return m_nIndexCount; }; 91 | 92 | UINT GetMaxDepth() const ; 93 | 94 | UINT GetLeafCount() const; 95 | 96 | /// Returns an estimate of the amount of memory used by the tree 97 | UINT GetMemoryUsage() const; 98 | 99 | /// Returns the scene bounding box 100 | const JRTBoundingBox& GetSceneBounds() const { return m_treeBounds; }; 101 | 102 | static const UINT OUT_OF_MEMORY = 0xffffffff; 103 | 104 | private: 105 | 106 | UINT RecurseMaxDepth(UINT nNode) const; 107 | 108 | 109 | friend class JRTKDTreeBuilder; 110 | JRTKDTree(); 111 | 112 | // *********************************************************** 113 | // Tree internals 114 | // *********************************************************** 115 | 116 | // tree bounding box 117 | JRTBoundingBox m_treeBounds; 118 | 119 | // number of nodes 120 | UINT m_nNodeCount; 121 | 122 | // number of triangles 123 | UINT m_nTriangleCount; 124 | 125 | // number of triangle indices 126 | UINT m_nIndexCount; 127 | 128 | // array of KDTree nodes 129 | JRTKDNode* m_pNodeArray; 130 | 131 | // array of triangle indices. All indices for all nodes are packed into contiguous memory. 132 | // each node stores an offset for its triangle list in this array 133 | UINT* m_pIndexArray; 134 | 135 | // array of pre-processed triangles 136 | JRTCoreTriangle* m_pTriArray; 137 | 138 | // next ray ID to assign to a traced ray 139 | UINT m_nNextRayID; 140 | 141 | 142 | //****************** Ray traversal state *********************** 143 | 144 | // this is mutable state that changes during ray traversal. If we every want 145 | // to make this thing multi-threaded, we will need to allocate this stuff seperately 146 | // for each worker thread 147 | 148 | 149 | // mailboxes, one per triangle. These store the ray-id for the last ray to be tested 150 | // with this triangle 151 | UINT* m_pMailboxes; 152 | 153 | // flags to indicate whether or not a triangle is back-facing (TOOTLE SPECIFIC) 154 | bool* m_bBackFacing; 155 | 156 | }; 157 | 158 | #endif 159 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTKDTreeBuilder.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_KDTREE_BUILDER_H_ 7 | #define _JRT_KDTREE_BUILDER_H_ 8 | 9 | #include "JRTCommon.h" 10 | 11 | class JRTMesh; 12 | class JRTKDTree; 13 | class JRTTriangle; 14 | class JRTKDNode; 15 | class JRTBoundingBox; 16 | 17 | /// \brief The tree builder class is responsible for constructing a KD tree from triangle soup. 18 | /// The base implementation uses a stupid naive splitting heuristic 19 | class JRTKDTreeBuilder 20 | { 21 | public: 22 | 23 | JRTKDTree* BuildTree(const std::vector& rMeshes); 24 | 25 | protected: 26 | 27 | virtual void BuildTreeImpl(const JRTBoundingBox& rBounds, 28 | const std::vector& rTris, 29 | std::vector& rNodesOut, 30 | std::vector& rTriIndicesOut); 31 | 32 | 33 | }; 34 | 35 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTMesh.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include "JRTCommon.h" 8 | #include "JRTMesh.h" 9 | #include "JRTBoundingBox.h" 10 | 11 | /// A mesh must have an array of positions and connectivity. It may also have per-vertex normals 12 | /// If per-vertex normals are omitted, then per-face normals are used instead. 13 | /// 14 | /// The mesh does NOT delete the input arrays 15 | /// 16 | /// \param rPositions 17 | /// Array of vertex positions 18 | /// \param pFaceNormals 19 | /// Array of face normals. Must be same length as nTriangleCount 20 | /// \param nTriangleCount 21 | /// Number of triangles 22 | /// \param pIndices 23 | /// An array of 3*nTriangleCount vertex indices 24 | JRTMesh* JRTMesh::CreateMesh(const Vec3f* pPositions, 25 | const Vec3f* pNormals, 26 | UINT nVertices, 27 | UINT nTriangleCount, 28 | const UINT* pIndices) 29 | { 30 | JRTMesh* pMesh = new JRTMesh(); 31 | 32 | pMesh->m_nVertexCount = nVertices; 33 | pMesh->m_nTriangleCount = nTriangleCount; 34 | 35 | // copy vertex positions 36 | pMesh->m_Positions.assign (pPositions, pPositions + nVertices); 37 | 38 | // copy normals 39 | pMesh->m_FaceNormals.assign (pNormals, pNormals + nTriangleCount); 40 | 41 | // create triangles 42 | pMesh->m_Triangles.resize (nTriangleCount); 43 | 44 | for (UINT i = 0; i < nTriangleCount; i++) 45 | { 46 | pMesh->m_Triangles[i].m_pMesh = pMesh; 47 | 48 | JRT_ASSERT(pIndices[0] < nVertices); 49 | JRT_ASSERT(pIndices[1] < nVertices); 50 | JRT_ASSERT(pIndices[2] < nVertices); 51 | 52 | pMesh->m_Triangles[i].m_pV1 = reinterpret_cast (&pMesh->m_Positions[ pIndices[0] ]); 53 | pMesh->m_Triangles[i].m_pV2 = reinterpret_cast (&pMesh->m_Positions[ pIndices[1] ]); 54 | pMesh->m_Triangles[i].m_pV3 = reinterpret_cast (&pMesh->m_Positions[ pIndices[2] ]); 55 | 56 | pIndices += 3; 57 | } 58 | 59 | return pMesh; 60 | 61 | } 62 | 63 | JRTMesh::JRTMesh() : 64 | m_nTriangleCount(0), 65 | m_nVertexCount(0) 66 | { 67 | } 68 | 69 | 70 | JRTMesh::~JRTMesh() 71 | { 72 | } 73 | 74 | void JRTMesh::Transform(const Matrix4f& rXForm, const Matrix4f& rInverse) 75 | { 76 | // transform positions 77 | for (UINT i = 0; i < m_nVertexCount; i++) 78 | { 79 | TransformPoint(&m_Positions[i], &rXForm, &m_Positions[i]); 80 | } 81 | 82 | Matrix4f inverseTranspose = rInverse.Transpose(); 83 | 84 | // transform normals 85 | if (! m_Normals.empty ()) 86 | { 87 | for (UINT i = 0; i < m_nVertexCount; i++) 88 | { 89 | ALIGN16 Vec3f tmp = m_Normals[i]; 90 | TransformVector(&tmp, &inverseTranspose, &m_Normals[i]); 91 | m_Normals[i] = Normalize(m_Normals[i]); 92 | } 93 | } 94 | else 95 | { 96 | // transform face normals 97 | for (UINT i = 0; i < m_nTriangleCount; i++) 98 | { 99 | ALIGN16 Vec3f tmp = m_FaceNormals[i]; 100 | TransformVector(&tmp, &inverseTranspose, &m_FaceNormals[i]); 101 | m_FaceNormals[i] = tmp; 102 | } 103 | } 104 | } 105 | 106 | 107 | void JRTMesh::GetInterpolants(UINT nTriIndex, const float barycentrics[], Vec3f* pNormal, Vec2f* /*pUV*/) const 108 | { 109 | const UINT nIndex1 = (UINT)(m_Triangles[nTriIndex].m_pV1 - (const float*)m_Positions.data ()) / 3; 110 | const UINT nIndex2 = (UINT)(m_Triangles[nTriIndex].m_pV2 - (const float*)m_Positions.data ()) / 3; 111 | const UINT nIndex3 = (UINT)(m_Triangles[nTriIndex].m_pV3 - (const float*)m_Positions.data ()) / 3; 112 | 113 | if (!m_Normals.empty ()) 114 | { 115 | *pNormal = Normalize(BarycentricLerp3f(m_Normals[nIndex1], m_Normals[nIndex2], m_Normals[nIndex3], barycentrics)); 116 | } 117 | else 118 | { 119 | *pNormal = Normalize(m_FaceNormals[ nTriIndex ]); 120 | } 121 | } 122 | 123 | 124 | 125 | void JRTMesh::RemoveTriangle(UINT nTri) 126 | { 127 | if (nTri <= m_nTriangleCount) 128 | { 129 | // swap this triangle with the last one in the mesh 130 | JRTTriangle tmpTri = m_Triangles[m_nTriangleCount - 1]; 131 | m_Triangles[m_nTriangleCount - 1] = m_Triangles[nTri]; 132 | m_Triangles[nTri] = tmpTri; 133 | 134 | // swap face normals if there are any 135 | if (m_Normals.empty ()) 136 | { 137 | Vec3f tmpNorm = m_FaceNormals[ m_nTriangleCount - 1 ]; 138 | m_FaceNormals[m_nTriangleCount - 1] = m_FaceNormals[nTri]; 139 | m_FaceNormals[ nTri ] = tmpNorm; 140 | } 141 | 142 | m_nTriangleCount--; 143 | } 144 | } 145 | 146 | 147 | JRTBoundingBox JRTMesh::ComputeBoundingBox() const 148 | { 149 | return JRTBoundingBox((const float*)this->m_Positions.data (), m_nVertexCount); 150 | } -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTMesh.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_MESH_H_ 7 | #define _JRT_MESH_H_ 8 | 9 | #include "JRTCommon.h" 10 | 11 | class JRTTriangle; 12 | 13 | class JRTCSGNode; 14 | class JRTSurfaceShader; 15 | class JRTPhotonShader; 16 | class JRTBoundingBox; 17 | 18 | class JRTMeshAttributes 19 | { 20 | public: 21 | JRTMeshAttributes() : pShader(NULL), pCSGNode(NULL), bCastsShadows(true), bCastsCaustics(false) 22 | {}; 23 | 24 | JRTSurfaceShader* pShader; 25 | JRTPhotonShader* pPhotonShader; 26 | JRTCSGNode* pCSGNode; 27 | bool bCastsShadows; 28 | bool bCastsCaustics; 29 | }; 30 | 31 | 32 | class JRTMesh 33 | { 34 | public: 35 | 36 | /// Factory method for creating meshes 37 | static JRTMesh* CreateMesh(const Vec3f* pPositions, 38 | const Vec3f* pNormals, 39 | UINT nVertices, 40 | UINT nTriangleCount, 41 | const UINT* pIndices); 42 | 43 | /// Mesh constructor 44 | JRTMesh(); 45 | 46 | /// Mesh destructor 47 | ~JRTMesh(); 48 | 49 | /// Transforms the mesh and re-preprocesses the triangles 50 | void Transform(const Matrix4f& rXForm, const Matrix4f& rInverse); 51 | 52 | /// Returns the number of triangles in the mesh 53 | UINT GetTriangleCount() const { return m_nTriangleCount; }; 54 | 55 | /// Accessor for the array of triangles 56 | inline const JRTTriangle* GetTriangles() const { return m_Triangles.data (); }; 57 | 58 | 59 | void GetInterpolants(UINT nTriIndex, const float barycentrics[3], Vec3f* pNormal, Vec2f* pUV) const; 60 | 61 | const JRTMeshAttributes& GetAttributes() const { return m_attributes; }; 62 | 63 | void SetAttributes(const JRTMeshAttributes& rAttribs) { m_attributes = rAttribs; }; 64 | 65 | /// Removes a particular triangle from the mesh 66 | void RemoveTriangle(UINT nTri); 67 | 68 | JRTBoundingBox ComputeBoundingBox() const; 69 | 70 | const Vec3f& GetFaceNormal(UINT nTri) const { return m_FaceNormals[nTri]; }; 71 | 72 | const Vec3f& GetVertex(UINT i) const { return m_Positions[i]; }; 73 | void SetVertex(UINT i, const Vec3f& v) { m_Positions[i] = v; }; 74 | 75 | private: 76 | 77 | std::vector m_Positions; 78 | std::vector m_Normals; 79 | std::vector m_UVs; 80 | 81 | /// Pre-computed array of face normals. This is used only if no vertex normals are provided 82 | std::vector m_FaceNormals; 83 | 84 | std::vector m_Triangles; 85 | 86 | UINT m_nTriangleCount; 87 | UINT m_nVertexCount; 88 | 89 | JRTMeshAttributes m_attributes; 90 | 91 | // Disallow copy constructor, as m_Triangles contains pointers into the 92 | // other data structures 93 | JRTMesh (const JRTMesh&); 94 | JRTMesh& operator=(const JRTMesh&); 95 | }; 96 | 97 | 98 | 99 | 100 | class JRTTriangle 101 | { 102 | public: 103 | 104 | /// Returns the first vertex 105 | inline const Vec3f& GetV1() const { return *(const Vec3f*)m_pV1; }; 106 | 107 | /// Returns the second vertex 108 | inline const Vec3f& GetV2() const { return *(const Vec3f*)m_pV2; }; 109 | 110 | /// Returns the third vertex 111 | inline const Vec3f& GetV3() const { return *(const Vec3f*)m_pV3; }; 112 | 113 | /// Returns the mesh which owns this triangle 114 | inline JRTMesh* GetMesh() const { return m_pMesh; }; 115 | 116 | /// Returns the index of this triangle in its parent's triangle array 117 | inline UINT GetIndexInMesh() const { return (UINT)(this - m_pMesh->GetTriangles()); }; 118 | 119 | inline const Vec3f& GetNormal() const { return m_pMesh->GetFaceNormal(GetIndexInMesh()); }; 120 | private: 121 | 122 | 123 | friend class JRTMesh; 124 | 125 | /// Pointer to first vertex position 126 | const float* m_pV1; 127 | 128 | /// Pointer to second vertex position 129 | const float* m_pV2; 130 | 131 | /// Pointer to third vertex position 132 | const float* m_pV3; 133 | 134 | /// Pointer to the mesh 135 | JRTMesh* m_pMesh; 136 | 137 | }; 138 | 139 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTOrthoCamera.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "JRTCommon.h" 7 | #include "TootlePCH.h" 8 | #include "JRTCommon.h" 9 | #include "JRTOrthoCamera.h" 10 | 11 | JRTOrthoCamera::JRTOrthoCamera(const Vec3f& rPosition, const Vec3f& rDirection, const Vec3f& rUp, float fHorizontalSize) 12 | : m_position(rPosition), m_direction(rDirection), m_fSize(fHorizontalSize), m_fAspect(1) 13 | { 14 | m_right = Normalize(Cross(rUp, m_direction)); 15 | m_up = Normalize(Cross(m_direction, m_right)); 16 | } 17 | 18 | 19 | void JRTOrthoCamera::GetRay(float s, float t, Vec3f* origin, Vec3f* delta) const 20 | { 21 | *delta = Normalize(m_direction); 22 | 23 | // map s,t into -0.5 to 0.5 space, and invert t 24 | s -= 0.5f; 25 | t -= 0.5f; 26 | t *= -1; 27 | 28 | // use that to compute offsets from camera origin 29 | Vec3f dx = m_right * (s * m_fSize); 30 | Vec3f dy = m_up * (t * m_fSize * m_fAspect); 31 | *origin = m_position + dx + dy; 32 | 33 | } 34 | 35 | 36 | void JRTOrthoCamera::ProjectPoint(const Vec3f& /*pt*/, float* /*s*/, float* /*t*/) const 37 | { 38 | // TODO 39 | JRT_ASSERT(false); 40 | } -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTOrthoCamera.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_ORTHO_CAMERA_H_ 7 | #define _JRT_ORTHO_CAMERA_H_ 8 | 9 | #include "JRTCamera.h" 10 | 11 | 12 | class JRTOrthoCamera : public JRTCamera 13 | { 14 | public: 15 | JRTOrthoCamera(const Vec3f& position, const Vec3f& direction, const Vec3f& up, float fSize); 16 | 17 | virtual void GetRay(float s, float t, Vec3f* origin, Vec3f* delta) const ; 18 | 19 | virtual void SetAspectRatio(float fAspect) { m_fAspect = fAspect; }; 20 | 21 | // returns the position of the given point in camera NDC space 22 | // if the point is not visible, s and t are each set to -1 23 | virtual void ProjectPoint(const Vec3f& pt, float* s, float* t) const ; 24 | 25 | const Vec3f& GetPosition() const { return m_position; }; 26 | const Vec3f& GetDirection() const { return m_direction; }; 27 | const Vec3f& GetUp() const { return m_up; }; 28 | 29 | private: 30 | 31 | float m_fSize; 32 | float m_fAspect; 33 | Vec3f m_position; 34 | Vec3f m_direction; 35 | Vec3f m_up; 36 | Vec3f m_right; 37 | }; 38 | 39 | 40 | 41 | 42 | 43 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTPPMImage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _IMAGE_H_ 7 | #define _IMAGE_H_ 8 | 9 | 10 | typedef struct tag_pixel 11 | { 12 | unsigned char r; 13 | unsigned char g; 14 | unsigned char b; 15 | 16 | } PIXEL; 17 | 18 | 19 | class JRTPPMImage 20 | { 21 | 22 | public: 23 | /*************************** 24 | * Image Constructor: 25 | * Sets the width and height of the image, in pixels 26 | * allocates memory for pixels. Each pixel is initialized to 27 | * 0,0,0 (black) 28 | ***************************/ 29 | JRTPPMImage(int width = 256, int height = 256); 30 | 31 | JRTPPMImage(const JRTPPMImage& img); 32 | 33 | const JRTPPMImage& operator=(const JRTPPMImage& img); 34 | 35 | /*************************** 36 | * Image Destructor: 37 | * Frees all dynamic memory. 38 | ***************************/ 39 | virtual ~JRTPPMImage(); 40 | 41 | /*************************** 42 | * Accessors/Mutators: 43 | * Accessors for width and height are provided. 44 | * they return the width or height of the image, in pixels 45 | ***************************/ 46 | inline int GetHeight() const { return p_miHeight;}; 47 | inline int GetWidth() const { return p_miWidth;}; 48 | 49 | 50 | 51 | void SetPixel(int x, int y, float r, float g, float b); 52 | 53 | 54 | /*********************************************************** 55 | * SaveFile 56 | * Outputs the image to a PPM (P6) file 57 | * with the specified filename. Returns true if the 58 | * output was a success, false if not. 59 | *********************************************************/ 60 | bool SaveFile(const char* sFile); 61 | 62 | /********************************************************* 63 | * LoadFile 64 | * Loads an image from a PPM (P6) file 65 | * with the specified filename. Returns true if 66 | * the image was loaded ok. False if it was not 67 | * 68 | ************************************************************/ 69 | bool LoadFile(const char* sFile); 70 | 71 | private: 72 | 73 | void AllocPixels(int iWidth, int iHeight); 74 | void FreePixels(); 75 | 76 | PIXEL* AccessPixel(int x, int y); 77 | 78 | PIXEL* p_mlpPixels; 79 | int p_miHeight; 80 | int p_miWidth; 81 | 82 | }; 83 | 84 | 85 | #endif 86 | 87 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/JRT/JRTTriangleIntersection.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JRT_TRIANGLE_INTERSECTION_H_ 7 | #define _JRT_TRIANGLE_INTERSECTION_H_ 8 | 9 | #include "JRTCommon.h" 10 | 11 | // Note to self: P4 cache lines: 64 bytes 12 | 13 | class JRTMesh; 14 | 15 | 16 | // JRTCoreTriangle is a struct which stores all of the information needed to perform 17 | // ray-triangle intersection. Some preprocessing is performed on the triangles to optimize the 18 | // intersection calculation. 19 | struct JRTCoreTriangle 20 | { 21 | // Nu and Nv are the smaller two components of the normal, divided by 22 | // the largest component of the normal. This eliminates some multiplies 23 | // from the intersection code (Ingo wald thought of this, not me) 24 | float Nu; 25 | float Nv; 26 | 27 | // Nd is equal to -d, where d is the D term of the plane equation (ax + by + cz + d = 0) 28 | float Nd; 29 | 30 | // largest component of normal 0 = x, 1 = y, 2 = z 31 | // this determines what plane to project into to compute barycentrics 32 | UINT max_normal_comp; 33 | 34 | JRTMesh* pMesh; // pointer back to the mesh 35 | UINT nTriIndex; // index of this triangle in the mesh 36 | 37 | // one of the vertices, projected into the 2D plane of choice 38 | float V0u; 39 | float V0v; 40 | 41 | // the two vectors from V0 to the other vertices, projected 42 | // and scaled by 1/E1xE2 43 | float E1u; 44 | float E1v; // first is vector from v0 to v1 45 | 46 | float E2u; // second is vector from v0 to v2 47 | float E2v; 48 | }; 49 | 50 | 51 | 52 | 53 | /** 54 | This function performs some pre-processing on a triangle to get it read for use by the 55 | ray-triangle intersector. This function does all kinds of magical pre-computation which allows 56 | the actual intersection code to be good and fast. 57 | 58 | The first three arguments are pointers to the vertex positions of the triangle (3-component float arrays). 59 | 60 | The last argument is a pointer to a Preprocessed triangle structure that will be filled with 61 | the pre-computed triangle information that the intersector uses. 62 | */ 63 | void PreprocessTri(const float* v1, const float* v2, const float* v3, JRTCoreTriangle* triOut1); 64 | 65 | 66 | 67 | /** 68 | Ray-Triangle Intersection routine: 69 | Arguments: 70 | tri - preprocessed triangle to be tested for intersection 71 | origin - ray origin 72 | direction - ray direction 73 | tmin, tmax - t value intervals to test for 74 | tout - pointer to a variable to receive the t value 75 | may NOT be null 76 | barycentrics - pointer to an array to receive the barycentric coordinates of the hit point, 77 | may be NULL 78 | 79 | If there is an intersection with t values ranging between tmin and tmax, then 80 | *tout and barycentrics are set, and true is returned 81 | 82 | If there is no such intersection, then the values of *tout and barycentrics do not change 83 | and false is returned 84 | */ 85 | bool RayTriangleIntersect(const JRTCoreTriangle* pTriInfo, const float* origin, const float* direction, float tmin, float tmax, float* tout, float barcentrics_out[3]); 86 | 87 | 88 | 89 | 90 | 91 | 92 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/Math/JML.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JML_H_ 7 | #define _JML_H_ 8 | 9 | #ifdef _LINUX 10 | #define ALIGN16 11 | #else 12 | // helpful alias for 16-byte alignment 13 | #define ALIGN16 __declspec(align(16)) 14 | #endif 15 | 16 | #include "JMLVec2.h" 17 | #include "JMLVec3.h" 18 | #include "JMLMatrix.h" 19 | #include "JMLFuncs.h" 20 | 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/Math/JMLFuncs.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JML_FUNCS_H_ 7 | #define _JML_FUNCS_H_ 8 | 9 | 10 | #include 11 | #include 12 | 13 | #include "JMLVec2.h" 14 | #include "JMLVec3.h" 15 | #include "JMLMatrix.h" 16 | #include "JMLSSEVec.h" 17 | 18 | const float PI = 3.1415926f; 19 | const float E = 2.718281828f; 20 | #define Max(f1,f2) ((f1>f2) ? f1 : f2 ) 21 | #define Min(f1,f2) ((f1 18 | class Matrix 19 | { 20 | public: 21 | 22 | Matrix() 23 | { 24 | // initialize to identity 25 | for (int i = 0; i < SIZE * SIZE; i++) 26 | { 27 | if (i % (SIZE + 1) == 0) 28 | { 29 | m_values[i] = (T)1; 30 | } 31 | else 32 | { 33 | m_values[i] = (T)0; 34 | } 35 | } 36 | }; 37 | 38 | Matrix(const T values[(SIZE * SIZE)]) 39 | { 40 | memcpy(m_values, values, (SIZE * SIZE)*sizeof(T)); 41 | }; 42 | 43 | Matrix(const Matrix& rhs) 44 | { 45 | *this = rhs; 46 | }; 47 | 48 | const Matrix& operator=(const Matrix& rhs) 49 | { 50 | memcpy(m_values, rhs.m_values, (SIZE * SIZE)*sizeof(T)); 51 | return *this; 52 | }; 53 | 54 | /// Returns pointer to matrix data in COLUMN-major order 55 | const T* GetValues() const { return m_values; }; 56 | T* GetValues() { return m_values; }; 57 | 58 | operator const T* () const { return (const T*) this; }; 59 | 60 | operator T* () { return (T*) this; }; 61 | 62 | Matrix& operator *= (const Matrix& rhs) 63 | { 64 | T newdata[(SIZE * SIZE)]; 65 | int i, j, x; 66 | 67 | for (j = 0; j < SIZE; j++) 68 | { 69 | for (i = 0; i < SIZE; i++) 70 | { 71 | /** loop across ith row and down jth column **/ 72 | newdata[(SIZE * i) + j] = 0.0; 73 | 74 | for (x = 0; x < SIZE; x++) 75 | { 76 | newdata[(SIZE * i) + j] += m_values[(SIZE * i) + x] * rhs.m_values[(SIZE * x) + j]; 77 | } 78 | } 79 | } 80 | 81 | memcpy(m_values, newdata, 16 * sizeof(T)); 82 | }; 83 | 84 | Matrix operator* (const Matrix& rhs) const 85 | { 86 | T newdata[(SIZE * SIZE)]; 87 | int i, j, x; 88 | 89 | for (j = 0; j < SIZE; j++) 90 | { 91 | for (i = 0; i < SIZE; i++) 92 | { 93 | /** loop across ith row and down jth column **/ 94 | newdata[(SIZE * i) + j] = 0.0; 95 | 96 | for (x = 0; x < SIZE; x++) 97 | { 98 | newdata[(SIZE * i) + j] += m_values[(SIZE * i) + x] * rhs.m_values[(SIZE * x) + j]; 99 | } 100 | } 101 | } 102 | 103 | return Matrix(newdata); 104 | } 105 | 106 | Matrix Transpose() const 107 | { 108 | T newdata[(SIZE * SIZE)]; 109 | 110 | int i, j; 111 | 112 | for (i = 0; i < SIZE; i++) 113 | { 114 | for (j = 0; j < SIZE; j++) 115 | { 116 | /** loop across ith row and down jth column **/ 117 | newdata[(SIZE * j) + i] = m_values[(SIZE * i) + j]; 118 | } 119 | } 120 | 121 | return Matrix(newdata); 122 | }; 123 | 124 | void Set(unsigned int row, unsigned int col, T val) 125 | { 126 | m_values[(col * SIZE) + row ] = val; 127 | }; 128 | 129 | T Get(unsigned int row, unsigned int col) const 130 | { 131 | return m_values[(col * SIZE) + row ]; 132 | }; 133 | 134 | private: 135 | 136 | T m_values[(SIZE * SIZE)]; 137 | 138 | }; 139 | 140 | 141 | typedef Matrix Matrix2f; 142 | typedef Matrix Matrix3f; 143 | typedef Matrix Matrix4f; 144 | 145 | typedef Matrix Matrix2d; 146 | typedef Matrix Matrix3d; 147 | typedef Matrix Matrix4d; 148 | 149 | }; 150 | 151 | 152 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/Math/JMLScalar.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JML_SCALAR_H_ 7 | #define _JML_SCALAR_H_ 8 | 9 | #include 10 | #include 11 | 12 | namespace JML 13 | { 14 | inline float RandomFloat() 15 | { 16 | return (float)rand() / (float) RAND_MAX; 17 | }; 18 | 19 | 20 | inline float FastSQRT(float v) 21 | { 22 | __m128 val = _mm_load1_ps(&v); 23 | val = _mm_sqrt_ss(val); 24 | return val.m128_f32[0]; 25 | }; 26 | 27 | inline float FastRSQ(float v) 28 | { 29 | __m128 val = _mm_load1_ps(&v); 30 | val = _mm_rsqrt_ss(val); 31 | float frsq = val.m128_f32[0]; 32 | return (0.5f * frsq) * (3.0f - (v * frsq) * frsq); 33 | }; 34 | 35 | }; 36 | 37 | 38 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/Math/JMLVec2.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JML_VEC2_H_ 7 | #define _JML_VEC2_H_ 8 | 9 | 10 | namespace JML 11 | { 12 | /// \brief A template class for two-component vectors. 13 | /** 14 | The template argument must be a numeric type 15 | */ 16 | template 17 | class Vec2 18 | { 19 | public: 20 | 21 | T x; 22 | T y; 23 | 24 | // ***************************************** 25 | // Constructors 26 | // ***************************************** 27 | 28 | /// Default constructor 29 | Vec2() : x((T)0), y((T)0) {}; 30 | 31 | /// Value constructor 32 | Vec2(const T& vx, const T& vy) : x(vx), y(vy) {}; 33 | 34 | /// Copy constructor 35 | Vec2(const Vec2& val) : x(val.x), y(val.y) {}; 36 | 37 | /// Single value constructor. Sets all components to the given value 38 | Vec2(const T& v) : x(v), y(v) {}; 39 | 40 | 41 | // ***************************************** 42 | // Conversions/Assignment/Indexing 43 | // ***************************************** 44 | 45 | /// cast to T* 46 | operator const T* () const { return (const T*)this; }; 47 | 48 | /// cast to T* 49 | operator T* () { return (T*)this; }; 50 | 51 | /// Indexing 52 | const T& operator[](int i) const { return ((const T*)this)[i]; }; 53 | T& operator[](int i) { return ((T*)this)[i]; }; 54 | 55 | /// Assignment 56 | const Vec2& operator=(const Vec2& rhs) { x = rhs.x; y = rhs.y; return *this; }; 57 | 58 | // ***************************************** 59 | // Comparison 60 | // ***************************************** 61 | 62 | /// Equality comparison 63 | bool operator==(const Vec2& rhs) const { return (x == rhs.x && y == rhs.y); }; 64 | 65 | /// Inequality comparision 66 | bool operator!=(const Vec2& rhs) const { return (x != rhs.x || y != rhs.y); }; 67 | 68 | // ***************************************** 69 | // Arithmetic 70 | // ***************************************** 71 | 72 | /// Addition 73 | const Vec2 operator+(const Vec2& rhs) const { return Vec2(x + rhs.x, y + rhs.y); }; 74 | 75 | /// Subtraction 76 | const Vec2 operator-(const Vec2& rhs) const { return Vec2(x - rhs.x, y - rhs.y);}; 77 | 78 | /// Multiply by scalar 79 | const Vec2 operator*(const T& v) const { return Vec2(x * v, y * v); }; 80 | 81 | /// Divide by scalar 82 | const Vec2 operator/(const T& v) const { return Vec2(x / v, y / v); }; 83 | 84 | /// Addition in-place 85 | Vec2& operator+= (const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; }; 86 | 87 | /// Subtract in-place 88 | Vec2& operator-= (const Vec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; }; 89 | 90 | /// Scalar multiply in-place 91 | Vec2& operator*= (const T& v) { x *= v; y *= v; return *this; }; 92 | 93 | /// Scalar divide in-place 94 | Vec2& operator/= (const T& v) { x /= v; y /= v; return *this; }; 95 | 96 | 97 | }; 98 | 99 | /// stream output 100 | template 101 | std::ostream& operator<<(std::ostream& sout, const Vec2& vec) 102 | { 103 | sout << "<" << vec.x << "," << vec.y << ">"; 104 | return sout; 105 | }; 106 | 107 | typedef Vec2 Vec2f; 108 | typedef Vec2 Vec2d; 109 | typedef Vec2 Vec2i; 110 | 111 | 112 | 113 | 114 | }; 115 | 116 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/Math/JMLVec3.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _JML_VEC3_H_ 7 | #define _JML_VEC3_H_ 8 | 9 | 10 | namespace JML 11 | { 12 | /// \brief A template class for two-component vectors. 13 | /** 14 | The template argument must be a numeric type 15 | */ 16 | template 17 | class Vec3 18 | { 19 | public: 20 | 21 | T x; 22 | T y; 23 | T z; 24 | 25 | // ***************************************** 26 | // Constructors 27 | // ***************************************** 28 | 29 | /// Default constructor 30 | Vec3() : x((T)0), y((T)0), z((T)0) {}; 31 | 32 | /// Value constructor 33 | Vec3(const T& vx, const T& vy, const T& vz) : x(vx), y(vy), z(vz) {}; 34 | 35 | /// Copy constructor 36 | Vec3(const Vec3& val) : x(val.x), y(val.y), z(val.z) {}; 37 | 38 | /// Single value constructor. Sets all components to the given value 39 | Vec3(const T& v) : x(v), y(v), z(v) {}; 40 | 41 | /// Array constructor. Assumes a 3-component array 42 | Vec3(const T* v) : x(v[0]), y(v[1]), z(v[2]) {}; 43 | 44 | // ***************************************** 45 | // Conversions/Assignment/Indexing 46 | // ***************************************** 47 | 48 | /// cast to T* 49 | operator const T* () const { return (const T*)this; }; 50 | 51 | /// cast to T* 52 | operator T* () { return (T*)this; }; 53 | 54 | /// Assignment 55 | const Vec3& operator=(const Vec3& rhs) { x = rhs.x; y = rhs.y; z = rhs.z; return *this; }; 56 | 57 | // ***************************************** 58 | // Comparison 59 | // ***************************************** 60 | 61 | /// Equality comparison 62 | bool operator==(const Vec3& rhs) const { return (x == rhs.x && y == rhs.y && z == rhs.z); }; 63 | 64 | /// Inequality comparision 65 | bool operator!=(const Vec3& rhs) const { return (x != rhs.x || y != rhs.y || z != rhs.z); }; 66 | 67 | // ***************************************** 68 | // Arithmetic 69 | // ***************************************** 70 | 71 | /// Addition 72 | const Vec3 operator+(const Vec3& rhs) const { return Vec3(x + rhs.x, y + rhs.y, z + rhs.z); }; 73 | 74 | /// Subtraction 75 | const Vec3 operator-(const Vec3& rhs) const { return Vec3(x - rhs.x, y - rhs.y, z - rhs.z);}; 76 | 77 | /// Multiply by scalar 78 | const Vec3 operator*(const T& v) const { return Vec3(x * v, y * v, z * v); }; 79 | 80 | /// Divide by scalar 81 | const Vec3 operator/(const T& v) const { return Vec3(x / v, y / v, z / v); }; 82 | 83 | /// Divide by vector 84 | const Vec3 operator/(const Vec3& rhs) const { return Vec3(x / rhs.x, y / rhs.y, z / rhs.z); }; 85 | 86 | /// Addition in-place 87 | Vec3& operator+= (const Vec3& rhs) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; }; 88 | 89 | /// Subtract in-place 90 | Vec3& operator-= (const Vec3& rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }; 91 | 92 | /// Scalar multiply in-place 93 | Vec3& operator*= (const T& v) { x *= v; y *= v; z *= v; return *this; }; 94 | 95 | /// Scalar divide in-place 96 | Vec3& operator/= (const T& v) { x /= v; y /= v; z /= v; return *this; }; 97 | }; 98 | 99 | /// stream output 100 | template 101 | std::ostream& operator<<(std::ostream& sout, const Vec3& vec) 102 | { 103 | sout << "<" << vec.x << "," << vec.y << "," << vec.z << ">"; 104 | return sout; 105 | }; 106 | 107 | typedef Vec3 Vec3f; 108 | typedef Vec3 Vec3d; 109 | typedef Vec3 Vec3i; 110 | 111 | }; 112 | 113 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/TootleRaytracer.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | 7 | #ifndef _TOOTLE_RAYTRACER_H_ 8 | #define _TOOTLE_RAYTRACER_H_ 9 | 10 | 11 | class JRTCore; 12 | class JRTMesh; 13 | class JRTOrthoCamera; 14 | 15 | #include 16 | 17 | struct TootleRayHit; 18 | 19 | /// An overdraw table is a table that determines, for a pair of faces, how much one face overdraws the other 20 | typedef std::vector< std::vector > TootleOverdrawTable; 21 | 22 | 23 | /// \brief A class which resolves triangle visibility for Tootle, using ray tracing. 24 | class TootleRaytracer 25 | { 26 | public: 27 | TootleRaytracer(); 28 | 29 | ~TootleRaytracer(); 30 | 31 | /// Initializes the ray tracer and builds all of the necessary data structures 32 | bool Init(const float* pVertexPositions, const unsigned int* pIndices, const float* pFaceNormals, unsigned int nVertices, 33 | unsigned int nFaces, const unsigned int* pFaceClusters); 34 | 35 | /// Computes an overdraw table for a set of viewpoints. 36 | bool CalculateOverdraw(const float* pViewpoints, unsigned int nViewpoints, unsigned int nImageSize, 37 | bool bCullCCW, TootleOverdrawTable* pODArray); 38 | 39 | // Measure the overdraw for a set of viewpoints. 40 | bool MeasureOverdraw(const float* pViewpoints, UINT nViewpoints, UINT nImageSize, bool bCullCCW, float& fAvgODOut, float& fMaxODOut); 41 | 42 | /// Cleans up the internal data structures 43 | void Cleanup(); 44 | 45 | private: 46 | 47 | 48 | /// Renders the scene from a particular camera position and updates the overdraw array 49 | bool ProcessViewpoint(const float* pCameraPosition, unsigned int nImageSize, bool bCullCCW, TootleOverdrawTable* pODArray); 50 | 51 | /// Renders the scene from a particular camera position and measures the overdraw 52 | bool ProcessViewpoint(const float* pCameraPosition, unsigned int nImageSize, bool bCullCCW, 53 | unsigned int& nPixelHit, unsigned int& nPixelDrawn); 54 | 55 | /// Updates the overdraw table with overdraw that occurs for a particular pixel in the test image 56 | void ProcessPixel(TootleRayHit* pRayHit, unsigned int nHits, TootleOverdrawTable* pODArray); 57 | 58 | /// Compute the number of times for a particular pixel is drawn by the mesh 59 | void GetPixelDrawn(TootleRayHit* pRayHits, UINT nHits, UINT& nPixelOverdrawn); 60 | 61 | const unsigned int* m_pFaceClusters; 62 | JRTCore* m_pCore; 63 | JRTMesh* m_pMesh; 64 | }; 65 | 66 | #endif -------------------------------------------------------------------------------- /src/TootleLib/RayTracer/makefile: -------------------------------------------------------------------------------- 1 | CC = g++ -O3 -fpermissive -msse -D_SOFTWARE_ONLY_VERSION -D_LINUX 2 | #CC = g++ -g -Wall -fpermissive -msse -D_SOFTWARE_ONLY_VERSION -D_LINUX 3 | 4 | TOP = ../../.. 5 | TARGET = ${TOP}/lib/libRayTracer.a 6 | RTJRT = JRT 7 | RTMATH = Math 8 | 9 | CFLAGS = -I. -I../ -I../include -I${RTJRT} -I${RTMATH} 10 | 11 | LDFlags = -lm 12 | 13 | OBJECTS = TootleRaytracer.o ${RTJRT}/JRTBoundingBox.o ${RTJRT}/JRTCamera.o ${RTJRT}/JRTCore.o ${RTJRT}/JRTCoreUtils.o ${RTJRT}/JRTH2KDTreeBuilder.o ${RTJRT}/JRTHeuristicKDTreeBuilder.o ${RTJRT}/JRTKDTree.o ${RTJRT}/JRTKDTreeBuilder.o ${RTJRT}/JRTMesh.o ${RTJRT}/JRTOrthoCamera.o ${RTJRT}/JRTPPMImage.o ${RTJRT}/JRTTriangleIntersection.o ${RTMATH}/JMLFuncs.o 14 | 15 | CLEAN = ${TARGET} ${OBJECTS} *.o 16 | 17 | RayTracer: ${OBJECTS} 18 | ar -rs ${TARGET} *.o 19 | 20 | .cpp.o: 21 | ${CC} ${CFLAGS} -c $< 22 | 23 | .c.o: 24 | ${CC} ${CFLAGS} -c $< 25 | 26 | clean: 27 | /bin/rm -f ${CLEAN} 28 | -------------------------------------------------------------------------------- /src/TootleLib/Timer.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #ifdef _WIN32 8 | #include 9 | #else 10 | #include 11 | #include 12 | #endif 13 | 14 | #include "Timer.h" 15 | 16 | Timer:: 17 | Timer() 18 | { 19 | Reset(); 20 | } 21 | 22 | void 23 | Timer:: 24 | Reset(void) 25 | { 26 | time = Get(); 27 | } 28 | 29 | double 30 | Timer:: 31 | GetElapsed(void) 32 | { 33 | return Get() - time; 34 | } 35 | 36 | double 37 | Timer::Get(void) 38 | { 39 | #ifdef _WIN32 40 | FILETIME ft; 41 | GetSystemTimeAsFileTime(&ft); 42 | return ft.dwLowDateTime / 1.0e7 + ft.dwHighDateTime * (4294967296.0 / 1.0e7); 43 | #else 44 | struct timeval v; 45 | gettimeofday(&v, (struct timezone*) NULL); 46 | return v.tv_sec + v.tv_usec / 1.0e6; 47 | #endif 48 | } 49 | -------------------------------------------------------------------------------- /src/TootleLib/Timer.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _TIMER_H 7 | #define _TIMER_H 8 | 9 | class Timer 10 | { 11 | public: 12 | Timer(); 13 | void Reset(void); 14 | double GetElapsed(void); 15 | double Get(void); 16 | private: 17 | double time; 18 | }; 19 | 20 | #endif // _TIME_H 21 | -------------------------------------------------------------------------------- /src/TootleLib/TootlePCH.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _TOOTLEPCH_H_ 7 | #define _TOOTLEPCH_H_ 8 | 9 | // disable VC++ 2K5 warnings about deprecated standard C functions 10 | #if defined( _MSC_VER ) 11 | #if _MSC_VER >= 1400 12 | #define _CRT_SECURE_NO_DEPRECATE 13 | #endif 14 | #endif 15 | 16 | #ifdef _LINUX 17 | #define __cdecl 18 | #define _isnan(x) isnan(x) 19 | #define _finite(x) finite(x) 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #else 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #endif 44 | 45 | // suppress Debug and error output stream for both release and debug builds 46 | #define ERROR_SILENT 47 | //#define _SOFTWARE_ONLY_VERSION // compile with this flag for no dependency on GPU or Direct3D 48 | 49 | #include 50 | #include 51 | 52 | #ifdef _DX11_1_ 53 | 54 | /* 55 | Starting with Windows 8, the DirectX SDK is included as part of the Windows SDK. 56 | more information at https://msdn.microsoft.com/en-us/library/windows/desktop/ee663275(v=vs.85).aspx 57 | */ 58 | 59 | #include 60 | 61 | #endif 62 | 63 | #endif // _SU_TOOTLEPCH_H_ 64 | -------------------------------------------------------------------------------- /src/TootleLib/aligned_malloc.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | // This is the implementation of address-aligned malloc and free using a linked list (inserting at front). 7 | // These functions are not thread-safe because there is an access to the addressList global variable. 8 | // Use a mutex when you access the global variable to make it thread-safe. 9 | #include 10 | #include 11 | 12 | // a linked list node to store a coupled memory address of the original and aligned address. 13 | typedef struct llnode 14 | { 15 | void* original; // store the original starting address 16 | void* aligned; // store the aligned starting address 17 | struct llnode* next; 18 | } node; 19 | 20 | static node* s_addressList = NULL; 21 | static void PrintList(); 22 | template 23 | static T GetNextPowerOfTwo(T nValue); 24 | 25 | //================================================================================================================================= 26 | /// Takes the size of the buffer you would like to allocate with the return buffer starts on an alignment boundary (multiple of 27 | /// alignment input specified). The input alignment should be a power of 2. 28 | /// The memory allocated through aligned_malloc has to be deallocated by aligned_free. Otherwise the result will be unspecified. 29 | /// 30 | /// \param bytes The number of bytes requested. 31 | /// \param alignment The alignment required for the output address of the memory. This should be of a power of 2 32 | /// (i.e. 1, 2, 4, 8, 16, ...). 33 | /// 34 | /// \return The starting address of the allocated memory. The address will be aligned to the specified request. 35 | //================================================================================================================================= 36 | void* aligned_malloc(size_t bytes, size_t alignment) 37 | { 38 | // sanity checks 39 | if (bytes <= 0) 40 | { 41 | return NULL; 42 | } 43 | 44 | // if alignment is less than equal to zero, we set it to 1. 45 | alignment = (alignment <= 0) ? 1 : alignment; 46 | 47 | // make sure alignment is of power of 2. 48 | if ((alignment & (alignment - 1)) != 0) 49 | { 50 | // alignment is not of power of 2, round it to the next power of 2. 51 | alignment = GetNextPowerOfTwo(alignment); 52 | 53 | #if defined(_MSC_VER) && _MSC_VER < 1900 54 | fprintf (stderr, "aligned_malloc: rounding the alignment to %Iu\n", alignment); 55 | #else 56 | fprintf (stderr, "aligned_malloc: rounding the alignment to %zu\n", alignment); 57 | #endif 58 | } 59 | 60 | // request memory larger than the input request size to 61 | // accomodate alignment size. In the worst case we waste 62 | // alignment - 1 bytes. 63 | size_t totalSize = bytes + alignment - 1; 64 | 65 | void* memory; 66 | 67 | if ((memory = malloc(totalSize)) == NULL) 68 | { 69 | return NULL; 70 | } 71 | 72 | // Compute the offset alignment to add to the address. Because alignment is guaranteed to be power of 2, 73 | // we do not need to use modulus operator. The second line ensures that if the original address 74 | // already address aligned, the offset should be 0. 75 | size_t offset; 76 | offset = alignment - ((size_t) memory & (alignment - 1)); 77 | offset = (offset == alignment) ? 0 : offset; 78 | 79 | void* originalAddress = memory; 80 | memory = (void*)((size_t) memory + offset); 81 | 82 | // Store a coupled entry of address and aligned address into a linked list so we can free the memory with the correct 83 | // address in aligned_free() function. The new coupled entry is prepended into the linked list. The next code makes sure 84 | // that the linked list does not store multiple entry of the same memory address. 85 | node* addressEntry; 86 | 87 | for (addressEntry = s_addressList; 88 | addressEntry != NULL; 89 | addressEntry = addressEntry->next) 90 | { 91 | if (addressEntry->aligned == memory) 92 | { 93 | fprintf(stderr, "Error: malloc returns duplicate address.\n"); 94 | free(originalAddress); 95 | return NULL; 96 | } 97 | } 98 | 99 | addressEntry = (node*) malloc(sizeof(node)); 100 | addressEntry->original = originalAddress; 101 | addressEntry->aligned = memory; 102 | addressEntry->next = s_addressList; 103 | s_addressList = addressEntry; 104 | 105 | return memory; 106 | } 107 | 108 | 109 | //================================================================================================================================= 110 | // Print the linked-list, used for debugging purposes. 111 | // 112 | // \return void 113 | //================================================================================================================================= 114 | void PrintList() 115 | { 116 | node* addressEntry; 117 | 118 | fprintf(stderr, "List = "); 119 | 120 | for (addressEntry = s_addressList; 121 | addressEntry != NULL; 122 | addressEntry = addressEntry->next) 123 | { 124 | fprintf(stderr, "(o = %p, a = %p), ", 125 | addressEntry->original, addressEntry->aligned); 126 | } 127 | 128 | fprintf(stderr, "\n"); 129 | } 130 | 131 | //================================================================================================================================= 132 | // Free the allocated memory by aligned_malloc function call. 133 | // 134 | // \param p the starting address of the memory to be deallocated. 135 | // 136 | // \return void 137 | //================================================================================================================================= 138 | void aligned_free(void* p) 139 | { 140 | if (p == NULL) 141 | { 142 | return; 143 | } 144 | 145 | node* addressEntry; 146 | node* prevAddressEntry; 147 | 148 | prevAddressEntry = s_addressList; 149 | 150 | for (addressEntry = s_addressList; 151 | addressEntry != NULL; 152 | addressEntry = addressEntry->next) 153 | { 154 | if (addressEntry->aligned == p) 155 | { 156 | free(addressEntry->original); 157 | 158 | prevAddressEntry->next = addressEntry->next; 159 | 160 | // if we are deleting the head node, update the head node 161 | if (s_addressList == addressEntry) 162 | { 163 | s_addressList = addressEntry->next; 164 | } 165 | 166 | free(addressEntry); 167 | 168 | return; 169 | } 170 | 171 | prevAddressEntry = addressEntry; 172 | } 173 | 174 | fprintf(stderr, "Error: Can't free pointer = %p\n", p); 175 | 176 | return; 177 | } 178 | 179 | //================================================================================================================================= 180 | // Round a number up to the next power of two number. If the number is already a power of 2, it returns the same number. 181 | // This function only works for 32 bits number. 182 | // 183 | // \param nValue The input value to be rounded up. 184 | // 185 | // \return the next power of two 186 | //================================================================================================================================= 187 | template 188 | T GetNextPowerOfTwo(T nValue) 189 | { 190 | if (nValue < 1) 191 | { 192 | return 1; 193 | } 194 | 195 | nValue--; 196 | 197 | // change all the bits to the right of the highest significant bit to 1. 198 | for (unsigned int i = 1; i <= 16; i *= 2) 199 | { 200 | nValue |= (nValue >> i); 201 | } 202 | 203 | nValue++; 204 | 205 | return nValue; 206 | } 207 | 208 | -------------------------------------------------------------------------------- /src/TootleLib/aligned_malloc.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | // This is the interface of address-aligned malloc and free. 6 | ****************************************************************************************/ 7 | #ifndef _ALIGNED_MALLOC_H 8 | #define _ALIGNED_MALLOC_H 9 | 10 | //================================================================================================================================= 11 | /// \brief Allocate a memory such that the starting address will be aligned to the specified alignment. 12 | //================================================================================================================================= 13 | void* aligned_malloc(size_t bytes, size_t alignment); 14 | 15 | //================================================================================================================================= 16 | /// \brief Free the memory allocated by aligned_malloc(). 17 | //================================================================================================================================= 18 | void aligned_free(void* p); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/TootleLib/bbox.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _BBOX_ 7 | #define _BBOX_ 8 | 9 | #include "scalar.h" 10 | #include "matrix.h" 11 | 12 | template class BBox 13 | { 14 | public: 15 | BBox(void) 16 | { 17 | Reset(); 18 | } 19 | void Reset(void) 20 | { 21 | for (int i = 0; i < N; i++) 22 | { 23 | min[i] = SCALAR_MAX; 24 | max[i] = SCALAR_MIN; 25 | } 26 | 27 | changed = false; 28 | } 29 | BBox(const Matrix& _min, const Matrix& _max) 30 | { 31 | min = _min; 32 | max = _max; 33 | center = (max + min) / 2; 34 | changed = false; 35 | } 36 | void Merge(const Matrix& p) 37 | { 38 | for (int i = 0; i < N; i++) 39 | { 40 | if (p[i] < min[i]) { min[i] = p[i]; } 41 | 42 | if (p[i] > max[i]) { max[i] = p[i]; } 43 | } 44 | 45 | changed = true; 46 | } 47 | bool In(const Matrix& p) const 48 | { 49 | for (int i = 0; i < N; i++) 50 | { 51 | if (p[i] <= min[i]) { return false; } 52 | 53 | if (p[i] > max[i]) { return false; } 54 | } 55 | 56 | return true; 57 | } 58 | Matrix GetMin(void) const { return min; } 59 | Matrix GetMax(void) const { return max; } 60 | Matrix GetSize() const { return max - min; } 61 | Matrix GetCenter(void) 62 | { 63 | if (changed) { center = (max + min) / 2.0; } 64 | 65 | return center; 66 | } 67 | 68 | private: 69 | Matrix min, max; 70 | Matrix center; 71 | bool changed; 72 | }; 73 | 74 | typedef BBox<2> BBox2; 75 | typedef BBox<3> BBox3; 76 | 77 | #endif // _BBOX_ 78 | -------------------------------------------------------------------------------- /src/TootleLib/cloud.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef CLOUD_H 7 | #define CLOUD_H 8 | 9 | #include "vector.h" 10 | #include "color.h" 11 | 12 | class Cloud 13 | { 14 | public: 15 | // default constructor 16 | Cloud(void) 17 | { 18 | } 19 | 20 | // destructor 21 | virtual ~Cloud() 22 | { 23 | } 24 | 25 | // vertex access functions 26 | const Vector3& v(int i) const { return pv[i]; } 27 | Vector3& v(int i) { return pv[i]; } 28 | // vertex std::vector access functions 29 | std::vector& v(void) { return pv; } 30 | const std::vector& v(void) const { return pv; } 31 | void v (const std::vector& new_v) { pv = new_v; } 32 | // normal access functions 33 | const Vector3& n(int i) const { return (pn)[i]; } 34 | Vector3& n(int i) { return (pn)[i]; } 35 | // normal std::vector access functions 36 | std::vector& n(void) { return pn; } 37 | const std::vector& n(void) const { return pn; } 38 | void n (const std::vector& new_n) { pn = new_n; } 39 | // color access functions 40 | const Color& c(int i) const { return pc[i]; } 41 | Color& c(int i) { return pc[i]; } 42 | // color std::vector access functions 43 | std::vector& c(void) { return pc; } 44 | const std::vector& c(void) const { return pc; } 45 | void c (const std::vector& new_c) { pc = new_c; } 46 | // vertex confidence access functions 47 | float vc(int i) const { return pvc[i]; } 48 | float& vc(int i) { return pvc[i]; } 49 | // vertex confidence std::vector access functions 50 | std::vector& vc(void) { return pvc; } 51 | const std::vector& vc(void) const { return pvc; } 52 | void vc(const std::vector& new_vc) 53 | { pvc = new_vc; } 54 | protected: 55 | std::vector pv; // vertices 56 | std::vector pn; // normals 57 | std::vector pc; // colors 58 | std::vector pvc; // vertex confidence 59 | private: 60 | // prevent copy constructors and assignments 61 | Cloud (const Cloud& other); 62 | Cloud& operator=(const Cloud& other); 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/TootleLib/clustering.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef CLUSTERING_H 7 | #define CLUSTERING_H 8 | 9 | enum ClusterResult 10 | { 11 | CLUSTER_OK, 12 | CLUSTER_OUT_OF_MEMORY ///< Out of memory 13 | }; 14 | 15 | 16 | /// Performs face clustering and returns an array with the cluster ID for each face 17 | ClusterResult Cluster(Soup* soup, UINT& nClusters, std::vector& cluster); 18 | 19 | /// Sorts faces by cluster 20 | bool SortFacesByCluster(Soup& soup, std::vector& clusterIDs, UINT* pFaceRemap); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/TootleLib/color.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef COLOR_H 7 | #define COLOR_H 8 | 9 | #include "matrix.h" 10 | 11 | // shorthand declarations 12 | typedef Matrix<3, 1, float> Color; 13 | 14 | inline Color operator*(const Color& u, const Color& v) 15 | { 16 | return Color(u[0] * v[0], u[1] * v[1], u[2] * v[2]); 17 | } 18 | 19 | #endif // COLOR_H 20 | -------------------------------------------------------------------------------- /src/TootleLib/d3doverdrawwindow.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef D3DOVERDRAWWINDOW_H 7 | #define D3DOVERDRAWWINDOW_H 8 | 9 | #define NUM_QUERIES 100 10 | 11 | #include "d3dwindow.h" 12 | #include "soup.h" 13 | #include "feedback.h" 14 | 15 | __declspec(align(16)) class D3DOverdrawWindow: public D3DWindow 16 | { 17 | public: 18 | typedef D3DWindow Superclass; 19 | D3DOverdrawWindow(void); 20 | 21 | int SetSoup(Soup* pSoup); 22 | void SetViewpoint(const float* pViewpoint, UINT nViewpoints); 23 | void SetCluster(const std::vector* pCluster, const std::vector* pClusterStart); 24 | 25 | void SetCulling(bool bCullCCW); 26 | 27 | int LostDevice(void); 28 | int ResetDevice(void); 29 | int SetIB(void); 30 | int SetVB(void); 31 | int SetVD(void); 32 | int SetQuery(void); 33 | virtual int Display(void); 34 | virtual void Reshape(int w, int h); 35 | 36 | virtual void SetupWorld(void); 37 | virtual void SetupView(int iViewpoint); 38 | virtual void SetupProjection(void); 39 | virtual void SetupViewport(void); 40 | virtual void SetupTransforms(void); 41 | virtual void SetupUniforms(void); 42 | virtual void SetupDraw(int iViewpoint); 43 | virtual HRESULT DrawModel(void); 44 | virtual void DrawCluster(int iCluster); 45 | virtual void DrawComplement(int iClusterA, int iClusterB); 46 | virtual void Clear(void); 47 | virtual void Fit(void); 48 | virtual void FitClusters(void); 49 | 50 | virtual int Graph(std::vector& graph); 51 | virtual int Object(float& fOverdraw, float& fOverdrawMax); 52 | virtual int Loop(int iClusterA, int iClusterB); 53 | virtual int Loop(void); 54 | virtual bool NormalizedLoop(float& fOverdraw, float& fOverdrawMax); 55 | 56 | int CheckIsect(int iClusterA, int iClusterB); 57 | int CreateBuffers(void); 58 | int ReleaseBuffers(void); 59 | 60 | void* operator new(size_t i) 61 | { 62 | return _mm_malloc(i,16); 63 | } 64 | 65 | void operator delete(void* p) 66 | { 67 | _mm_free(p); 68 | } 69 | 70 | private: 71 | Soup* m_pSoup; 72 | const Vector3* m_pViewpoint; 73 | UINT m_nViewpointCount; 74 | 75 | const std::vector* m_pCluster; 76 | const std::vector* m_pClusterStart; 77 | IDirect3DQuery9* m_pOcclusionQuery[NUM_QUERIES]; 78 | IDirect3DQuery9* m_pOcclusionQueryPix[NUM_QUERIES]; 79 | 80 | LPDIRECT3DVERTEXBUFFER9 m_VB; 81 | LPDIRECT3DINDEXBUFFER9 m_IB; 82 | LPDIRECT3DVERTEXDECLARATION9 m_VD; 83 | int m_nVerts, m_nTris; 84 | 85 | #ifdef _DX11_1_ 86 | DirectX::XMMATRIX 87 | #else 88 | D3DXMATRIXA16 89 | #endif 90 | m_mViewing, m_mProjection, m_mWorld; 91 | 92 | Vector3 m_vCenter; 93 | float m_fSize; 94 | std::vector m_vClusterCenter; 95 | std::vector m_vClusterDiag; 96 | std::vector m_fClusterSize; 97 | int m_iTested; 98 | int m_iRendered; 99 | 100 | bool m_bCullCCW; // if true, cull counter-clockwise faces, otherwise, cull clockwise faces 101 | }; 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/TootleLib/d3dwindow.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef D3DWINDOW_H 7 | #define D3DWINDOW_H 8 | 9 | #include "d3dwm.h" 10 | #include "gdiwindow.h" 11 | #include "error.h" 12 | 13 | class D3DWindow: public GDIWindow 14 | { 15 | public: 16 | typedef GDIWindow Superclass; 17 | D3DWindow(void) { d3d = NULL; } 18 | virtual ~D3DWindow(void) { ; } 19 | virtual void Destroy(void) 20 | { 21 | Superclass::Destroy(); 22 | 23 | if (d3d != NULL) 24 | { 25 | unsigned int nRef = d3d->Release(); 26 | 27 | if (nRef != 0) 28 | { 29 | debugf(("D3D RESOURCE LEAK FOUND")); 30 | } 31 | 32 | d3d = NULL; 33 | } 34 | } 35 | virtual void SetD3DDevice(LPDIRECT3DDEVICE9 d3d) { this->d3d = d3d; } 36 | virtual LPDIRECT3DDEVICE9 GetD3DDevice(void) const { return d3d; } 37 | virtual int LostDevice(void) { return 1; } 38 | virtual int ResetDevice(void) { return 1; } 39 | virtual int Reset(void) { return D3DWMResetWindow(this); } 40 | protected: 41 | LPDIRECT3DDEVICE9 d3d; 42 | }; 43 | 44 | #endif // D3DWINDOW_H 45 | -------------------------------------------------------------------------------- /src/TootleLib/d3dwm.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | 8 | #include "gdiwm.h" 9 | #include "d3dwm.h" 10 | #include "d3dwindow.h" 11 | 12 | static LPDIRECT3D9 D3DWMContext = NULL; 13 | static int width = 512, height = 512; 14 | 15 | #define CREATE_WINDOW 16 | 17 | extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow(); 18 | 19 | int D3DWMOpen(void) 20 | { 21 | return (D3DWMContext = Direct3DCreate9(D3D_SDK_VERSION)) != NULL; 22 | } 23 | 24 | void D3DWMFillD3DPP(D3DPRESENT_PARAMETERS* d3dpp, HWND hWnd, int w, int h) 25 | { 26 | ZeroMemory(d3dpp, sizeof(D3DPRESENT_PARAMETERS)); 27 | d3dpp->Windowed = TRUE; 28 | d3dpp->hDeviceWindow = hWnd; 29 | d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD; 30 | d3dpp->EnableAutoDepthStencil = TRUE; 31 | d3dpp->AutoDepthStencilFormat = D3DFMT_D16; 32 | d3dpp->BackBufferFormat = D3DFMT_UNKNOWN; 33 | d3dpp->BackBufferWidth = w; 34 | d3dpp->BackBufferHeight = h; 35 | d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 36 | d3dpp->BackBufferCount = 2; 37 | } 38 | 39 | int D3DWMResetWindow(D3DWindow* window) 40 | { 41 | D3DPRESENT_PARAMETERS d3dpp; 42 | D3DWMFillD3DPP(&d3dpp, window->GetHandle(), window->GetWidth(), 43 | window->GetHeight()); 44 | return window->GetD3DDevice()->Reset(&d3dpp) == D3D_OK; 45 | } 46 | 47 | HWND D3DWMCreateWindow(const char* name, D3DWindow* window) 48 | { 49 | RECT r = {0, 0, width, height}; 50 | AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false); 51 | // Create the application's window 52 | 53 | #ifdef CREATE_WINDOW 54 | HWND hWnd = CreateWindowEx(0, 55 | "static", 56 | NULL, 0x0, 57 | CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); 58 | #else 59 | HWND hWnd = GetConsoleWindow(); 60 | #endif 61 | 62 | // if it is a d3d window, create a D3D device for it 63 | D3DPRESENT_PARAMETERS d3dpp; 64 | D3DWMFillD3DPP(&d3dpp, hWnd, width, height); 65 | HRESULT hr; 66 | 67 | 68 | LPDIRECT3DDEVICE9 device; 69 | 70 | if (FAILED(hr = D3DWMContext->CreateDevice(D3DADAPTER_DEFAULT, 71 | D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE, &d3dpp, &device))) 72 | { 73 | return NULL; 74 | } 75 | 76 | window->SetD3DDevice(device); 77 | window->SetHandle(hWnd); 78 | window->Create(); 79 | window->Reshape(width, height); 80 | window->ResetDevice(); 81 | //SetWindowLong(hWnd, 0, *(LONG *) (&window)); 82 | // Show the window 83 | //ShowWindow(hWnd, SW_SHOWDEFAULT); 84 | //UpdateWindow(hWnd); 85 | return hWnd; 86 | } 87 | 88 | int D3DWMDestroyWindow(D3DWindow* window) 89 | { 90 | window->Destroy(); 91 | #ifdef CREATE_WINDOW 92 | DestroyWindow(window->GetHandle()); 93 | #endif 94 | return 1; 95 | } 96 | 97 | int D3DWMClose(void) 98 | { 99 | if (D3DWMContext) 100 | { 101 | D3DWMContext->Release(); 102 | D3DWMContext = NULL; 103 | } 104 | 105 | return 0; 106 | } 107 | 108 | LRESULT CALLBACK D3DMsgProc(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam) 109 | { 110 | LONG L = GetWindowLong(hWnd, 0); 111 | D3DWindow* window = *(D3DWindow**)(&L); 112 | LPDIRECT3DDEVICE9 d3d = window ? window->GetD3DDevice() : NULL; 113 | 114 | switch (uMsg) 115 | { 116 | // Window size change event 117 | case WM_SIZE: 118 | window->LostDevice(); 119 | window->Reset(); 120 | window->ResetDevice(); 121 | window->Reshape(LOWORD(lParam), HIWORD(lParam)); 122 | InvalidateRect(hWnd, NULL, FALSE); 123 | return 0; 124 | 125 | // Window repaint callback 126 | case WM_PAINT: 127 | 128 | // reset device if it was lost 129 | if (d3d->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) 130 | { 131 | window->LostDevice(); 132 | window->Reset(); 133 | window->ResetDevice(); 134 | } 135 | 136 | // present only if window asks for it 137 | if (window->Display()) { d3d->Present(NULL, NULL, NULL, NULL); } 138 | 139 | ValidateRect(hWnd, NULL); 140 | return 0; 141 | 142 | // Time to leave the program... 143 | case WM_DESTROY: 144 | d3d->Release(); 145 | window->Destroy(); 146 | PostQuitMessage(0); 147 | return 0; 148 | 149 | default: 150 | break; 151 | } 152 | 153 | // Let the superclass window procedure handle the event 154 | return GDIMsgProc(hWnd, uMsg, wParam, lParam); 155 | } 156 | -------------------------------------------------------------------------------- /src/TootleLib/d3dwm.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef D3DWM_H 7 | #define D3DWM_H 8 | 9 | #include 10 | 11 | #ifdef _DX11_1_ 12 | #include 13 | #else 14 | #include 15 | #endif 16 | 17 | class D3DWindow; 18 | 19 | int D3DWMOpen(void); 20 | int D3DWMStartIdle(D3DWindow* window); 21 | int D3DWMStopIdle(D3DWindow* window); 22 | HWND D3DWMCreateWindow(const char* name, D3DWindow* window); 23 | LRESULT CALLBACK D3DMsgProc(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam); 24 | int D3DWMResetWindow(D3DWindow* window); 25 | int D3DWMDestroyWindow(D3DWindow* window); 26 | int D3DWMClose(void); 27 | 28 | #endif // D3DWM_H 29 | -------------------------------------------------------------------------------- /src/TootleLib/error.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | 8 | 9 | 10 | void error_output(const char *fmt, ...) 11 | { 12 | // disable all console output if ERROR_SILENT is defined 13 | #ifndef ERROR_SILENT 14 | va_list ap; 15 | va_start(ap, fmt); 16 | vfprintf(stderr, fmt, ap); 17 | va_end(ap); 18 | #else 19 | (void)fmt; 20 | #endif 21 | } 22 | -------------------------------------------------------------------------------- /src/TootleLib/error.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef ERROR_H 7 | #define ERROR_H 8 | 9 | #ifndef _DX11_1_ 10 | #ifdef __cplusplus 11 | extern "C" 12 | #endif 13 | #endif 14 | 15 | void error_output(const char* fmt, ...); 16 | 17 | #ifdef _LINUX 18 | #define warnf(args) 19 | #define errorf(args) 20 | #define assertf(cond, args) 21 | #else 22 | #define warnf(args) do { \ 23 | error_output("warning: %s: %d: ", __FILE__, __LINE__); \ 24 | error_output args; \ 25 | error_output("\n"); \ 26 | } while(0) 27 | 28 | #define errorf(args) do { \ 29 | error_output("error: %s: %d: ", __FILE__, __LINE__); \ 30 | error_output args; \ 31 | error_output("\n"); \ 32 | } while(0) 33 | 34 | #define assertf(cond, args) do { \ 35 | if (!(cond)) { \ 36 | error_output("assert: %s: %d: ", __FILE__, __LINE__); \ 37 | error_output args; \ 38 | error_output("\n"); \ 39 | exit(1); \ 40 | } \ 41 | } while(0) 42 | #endif 43 | 44 | #ifndef ERROR_NDEBUG 45 | #ifdef _LINUX 46 | #define debugf(args) 47 | #else 48 | #define debugf(args) do { \ 49 | const char *s = strrchr(__FILE__, '/'); \ 50 | if(!s) \ 51 | s = strrchr(__FILE__, '\\'); \ 52 | if(s) \ 53 | s++; \ 54 | else \ 55 | s = __FILE__; \ 56 | error_output("debug: %s: %d: ", s, __LINE__); \ 57 | error_output args; \ 58 | error_output("\n"); \ 59 | } while(0) 60 | #endif 61 | #else 62 | #define debugf 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/TootleLib/feedback.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "heap.h" 13 | #include "feedback.h" 14 | #include "error.h" 15 | 16 | // Arc array 17 | typedef struct _ARC 18 | { 19 | int i, j, c; 20 | } ARC, *PARC; 21 | PARC arc;//renamed to arc, because of function redefinition error. Conflicts with name of function "Arc" in windows.h 22 | 23 | // Per-vertex number of arcs 24 | static int* ArcCount; 25 | // Per-vertex section in arc list 26 | static PARC* ArcStart; 27 | 28 | // In-cost - Out-cost 29 | static int* DeltaCost; 30 | // Out degree 31 | static int* OutDegree; 32 | // In degree 33 | static int* InDegree; 34 | 35 | // Output ordering 36 | static int* Ordered; 37 | static int iFirst, iLast; 38 | 39 | // Zero degree 40 | static int* Zero; 41 | static int nZero; 42 | 43 | // Heap 44 | p_heap H, *Heap = &H; 45 | 46 | #if 0 47 | static int cmp(const void* va, const void* vb) 48 | { 49 | PARC a = (PARC) va; 50 | PARC b = (PARC) vb; 51 | 52 | if (a->i < b->i) { return -1; } 53 | else if (a->i > b->i) { return 1; } 54 | else if (a->j < b->j) { return -1; } 55 | else if (a->j > b->j) { return 1; } 56 | else { return 0; } 57 | } 58 | #endif 59 | 60 | static int cmp(const void* va, const void* vb) 61 | { 62 | PARC a = (PARC) va; 63 | PARC b = (PARC) vb; 64 | 65 | if (a->i < b->i) { return -1; } 66 | else if (a->i > b->i) { return 1; } 67 | else if (a->c * b->c > 0) 68 | { 69 | if (a->j < b->j) { return -1; } 70 | else if (a->j > b->j) { return 1; } 71 | else { return 0; } 72 | } 73 | else if (a->c < b->c) { return -1; } 74 | else if (a->c > b->c) { return 1; } 75 | else { return 0; } 76 | } 77 | 78 | 79 | void Output(int v) 80 | { 81 | // Kick out of heap 82 | heap_remove(Heap, v); 83 | 84 | // In cost < Out cost, should go first 85 | if (DeltaCost[v] < 0) 86 | { 87 | Ordered[iFirst++] = v; 88 | // Out cost < In cost, should go last 89 | } 90 | else if (DeltaCost[v] > 0) 91 | { 92 | Ordered[iLast--] = v; 93 | // In cost == Out cost, check degrees 94 | // If out degree is higher, should go first 95 | } 96 | else if (InDegree[v] < OutDegree[v]) 97 | { 98 | Ordered[iFirst++] = v; 99 | // otherwise should go last 100 | } 101 | else 102 | { 103 | Ordered[iLast--] = v; 104 | } 105 | 106 | // Update data due to removal of vertex 107 | PARC pA = ArcStart[v]; 108 | 109 | for (int i = 0; i < ArcCount[v]; i++) 110 | { 111 | if (heap_position(Heap, pA[i].j) <= 0) { continue; } 112 | 113 | DeltaCost[pA[i].j] -= pA[i].c; 114 | heap_update(Heap, pA[i].j, -abs(DeltaCost[pA[i].j])); 115 | 116 | // out arc 117 | if (pA[i].c > 0) 118 | { 119 | InDegree[pA[i].j]--; 120 | 121 | if (InDegree[pA[i].j] == 0 && OutDegree[pA[i].j] != 0) 122 | { 123 | Zero[nZero++] = pA[i].j; 124 | } 125 | 126 | // in arc 127 | } 128 | else 129 | { 130 | OutDegree[pA[i].j]--; 131 | 132 | if (OutDegree[pA[i].j] == 0 && InDegree[pA[i].j] != 0) 133 | { 134 | Zero[nZero++] = pA[i].j; 135 | } 136 | } 137 | } 138 | } 139 | 140 | 141 | // helper macro to to test for out of memory. This makes the code below a bit more compact 142 | #define CHECK_OUT_OF_MEMORY(p) \ 143 | if( !p ) \ 144 | { \ 145 | return 1; \ 146 | } \ 147 | 148 | 149 | int feedback(int nVerts, int nArcs, t_edge* graph, int* order) 150 | { 151 | arc = (PARC) malloc(sizeof(ARC) * 2 * nArcs) ; 152 | DeltaCost = (int*) malloc(sizeof(int) * nVerts); 153 | ArcStart = (PARC*) malloc(sizeof(PARC*) * nVerts); 154 | Zero = (int*) malloc(sizeof(int) * nVerts); 155 | Ordered = (int*) malloc(sizeof(int) * nVerts); 156 | ArcCount = (int*) malloc(sizeof(int) * nVerts); 157 | OutDegree = (int*) malloc(sizeof(int) * nVerts); 158 | InDegree = (int*) malloc(sizeof(int) * nVerts); 159 | 160 | CHECK_OUT_OF_MEMORY(arc); 161 | CHECK_OUT_OF_MEMORY(DeltaCost); 162 | CHECK_OUT_OF_MEMORY(ArcStart); 163 | CHECK_OUT_OF_MEMORY(Zero); 164 | CHECK_OUT_OF_MEMORY(Ordered); 165 | CHECK_OUT_OF_MEMORY(ArcCount); 166 | CHECK_OUT_OF_MEMORY(OutDegree); 167 | CHECK_OUT_OF_MEMORY(InDegree); 168 | 169 | memset(arc, 0, sizeof(int) * 2 * nArcs); 170 | memset(DeltaCost, 0, sizeof(int) * nVerts); 171 | memset(ArcCount, 0, sizeof(int) * nVerts); 172 | memset(OutDegree, 0, sizeof(int) * nVerts); 173 | memset(InDegree, 0, sizeof(int) * nVerts); 174 | 175 | PARC pArc = arc; 176 | 177 | for (int a = 0; a < nArcs; a++) 178 | { 179 | int i, j, c; 180 | i = graph[a].from; 181 | j = graph[a].to; 182 | c = graph[a].cost; 183 | //printf("edge: %i %i %i\n", i, j, c); 184 | ArcCount[i]++; ArcCount[j]++; 185 | DeltaCost[i] -= c; DeltaCost[j] += c; 186 | InDegree[j]++; OutDegree[i]++; 187 | pArc->i = i; pArc->j = j; pArc->c = c; 188 | pArc++; 189 | pArc->i = j; pArc->j = i; pArc->c = -c; 190 | pArc++; 191 | } 192 | 193 | // Make sure edges are sorted by vertex index 194 | qsort(arc, 2 * nArcs, sizeof(ARC), cmp); 195 | 196 | // Find start of each vertex's section in edge list 197 | memset(ArcStart, 0, sizeof(PARC*) * nVerts); 198 | pArc = arc; 199 | 200 | for (int i = 0; i < nVerts; i++) 201 | { 202 | if (ArcCount[i] > 0) 203 | { 204 | ArcStart[i] = pArc; 205 | pArc += ArcCount[i]; 206 | } 207 | } 208 | 209 | // Allocate and initialize heap 210 | if (!heap_create(Heap, nVerts)) 211 | { 212 | errorf(("Out of memory.")); 213 | return 1; 214 | } 215 | 216 | for (int i = 0; i < nVerts; i++) 217 | { 218 | heap_insert(Heap, i, -abs(DeltaCost[i])); 219 | } 220 | 221 | // initialize stack of zero degree vertices 222 | nZero = 0; 223 | 224 | for (int i = 0; i < nVerts; i++) 225 | { 226 | if (InDegree[i] == 0 || OutDegree[i] == 0) 227 | { 228 | Zero[nZero++] = i; 229 | } 230 | } 231 | 232 | memset(Ordered, 0, sizeof(int) * nVerts); 233 | 234 | // While there are vertices to be output 235 | iFirst = 0; 236 | iLast = nVerts - 1; 237 | 238 | while (1) 239 | { 240 | // Output vertices with zero degree 241 | while (nZero > 0) 242 | { 243 | int v = Zero[--nZero]; 244 | Output(v); 245 | } 246 | 247 | if (iFirst > iLast) { break; } 248 | 249 | Output((int)heap_gettop(Heap, NULL)); 250 | 251 | if (iFirst > iLast) { break; } 252 | } 253 | 254 | // Output results 255 | //for (i = 0; i < nVerts; i++) 256 | // printf("%d\n", Ordered[i]); 257 | memcpy(order, Ordered, sizeof(int) * nVerts); 258 | 259 | // clean up 260 | free(arc); 261 | free(DeltaCost); 262 | free(ArcCount); 263 | free(OutDegree); 264 | free(InDegree); 265 | free(ArcStart); 266 | free(Zero); 267 | free(Ordered); 268 | heap_destroy(Heap); 269 | 270 | return 1; 271 | } 272 | -------------------------------------------------------------------------------- /src/TootleLib/feedback.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | 7 | #ifndef _TOOTLE_FEEDBACK_H_ 8 | #define _TOOTLE_FEEDBACK_H_ 9 | 10 | typedef struct _t_edge 11 | { 12 | int from, to, cost; 13 | } t_edge; 14 | 15 | int feedback(int nVerts, int nArcs, t_edge* graph, int* order); 16 | 17 | 18 | #endif -------------------------------------------------------------------------------- /src/TootleLib/fit.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include 8 | 9 | #include "bbox.h" 10 | #include "error.h" 11 | 12 | #include "fit.h" 13 | 14 | bool 15 | RobustFit(const std::vector& vertex, Vector3* ucenter, float* usize) 16 | { 17 | Vector3 center; 18 | float size; 19 | int nvertex; 20 | 21 | if ((nvertex = static_cast (vertex.size())) == 0) { return false; } 22 | 23 | // solve for x, y and z independently 24 | std::vector a, b, c; 25 | 26 | a.resize (nvertex); b.resize (nvertex); c.resize (nvertex); 27 | 28 | // copy coordinates to temp buffers 29 | for (int i = 0; i < nvertex; i++) 30 | { 31 | a[i] = vertex[i][0]; 32 | b[i] = vertex[i][1]; 33 | c[i] = vertex[i][2]; 34 | } 35 | 36 | // center is median independently in 3 dimensions 37 | std::nth_element(&a[0], &a[nvertex / 2], &a[nvertex]); 38 | std::nth_element(&b[0], &b[nvertex / 2], &b[nvertex]); 39 | std::nth_element(&c[0], &c[nvertex / 2], &c[nvertex]); 40 | center[0] = a[nvertex / 2]; 41 | center[1] = b[nvertex / 2]; 42 | center[2] = c[nvertex / 2]; 43 | 44 | // get median distance to median center 45 | for (int i = 0; i < nvertex; i++) 46 | { 47 | a[i] = Norm(vertex[i] - center); 48 | } 49 | 50 | b = a; 51 | std::nth_element(&b[0], &b[nvertex / 2], &b[nvertex]); 52 | float distance = b[nvertex / 2]; 53 | 54 | // compute median deviation from median distance to median center 55 | for (int i = 0; i < nvertex; i++) 56 | { 57 | b[i] = fabs(a[i] - distance); 58 | } 59 | 60 | c = b; 61 | std::nth_element(&c[0], &c[nvertex / 2], &c[nvertex]); 62 | float deviation = c[nvertex / 2]; 63 | // discard points that are too far away from center 64 | BBox3 box; 65 | 66 | for (int i = 0; i < nvertex; i++) 67 | { 68 | if (b[i] <= 2 * deviation) 69 | { 70 | box.Merge(vertex[i]); 71 | } 72 | } 73 | 74 | size = Norm(box.GetSize()); 75 | 76 | if (usize) { *usize = size; } 77 | 78 | if (ucenter) { *ucenter = center; } 79 | 80 | return true; 81 | } 82 | 83 | bool 84 | BBoxFit(const std::vector& vertex, Vector3* ucenter, float* usize) 85 | { 86 | Vector3 center; 87 | float size; 88 | int nvertex; 89 | 90 | if ((nvertex = static_cast (vertex.size())) == 0) { return false; } 91 | 92 | BBox3 box; 93 | 94 | for (int i = 0; i < nvertex; i++) 95 | { 96 | box.Merge(vertex[i]); 97 | } 98 | 99 | Vector3 s = box.GetSize(); 100 | size = Norm(s); 101 | center = box.GetMin() + s / 2; 102 | 103 | if (usize) { *usize = size; } 104 | 105 | if (ucenter) { *ucenter = center; } 106 | 107 | return true; 108 | } 109 | 110 | bool 111 | BBoxFit(const std::vector& vertex, const int* ind, int iStart, int nTris, 112 | Vector3* ucenter, Vector3* udiag, float* usize) 113 | { 114 | Vector3 center; 115 | Vector3 diag; 116 | float size; 117 | int nvertex; 118 | 119 | if ((nvertex = static_cast (vertex.size())) == 0) { return false; } 120 | 121 | BBox3 box; 122 | 123 | for (int i = iStart; i < iStart + nTris * 3; i++) 124 | { 125 | int c = ind[i]; 126 | box.Merge(vertex[c]); 127 | } 128 | 129 | diag = box.GetSize(); 130 | size = Norm(diag); 131 | center = box.GetMin() + diag / 2; 132 | 133 | if (usize) { *usize = size; } 134 | 135 | if (udiag) { *udiag = diag; } 136 | 137 | if (ucenter) { *ucenter = center; } 138 | 139 | return true; 140 | } 141 | -------------------------------------------------------------------------------- /src/TootleLib/fit.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef FIT_H 7 | #define FIT_H 8 | 9 | #include "vector.h" 10 | 11 | bool 12 | RobustFit(const std::vector& vertex, Vector3* ucenter, float* usize); 13 | 14 | bool 15 | BBoxFit(const std::vector& vertex, Vector3* ucenter, float* usize); 16 | 17 | bool 18 | BBoxFit(const std::vector& vertex, const int* ind, int iStart, int nTris, Vector3* ucenter, Vector3* udiag, float* usize); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/TootleLib/gdiwindow.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef GDIWINDOW_H 7 | #define GDIWINDOW_H 8 | 9 | #include "gdiwm.h" 10 | #include "window.h" 11 | 12 | class GDIWindow: public Window 13 | { 14 | public: 15 | typedef Window Superclass; 16 | GDIWindow() { m_hWnd = NULL; } 17 | virtual ~GDIWindow(void) { ; } 18 | virtual void Destroy(void) 19 | { 20 | Superclass::Destroy(); 21 | m_hWnd = NULL; 22 | } 23 | virtual HWND GetHandle(void) { return m_hWnd; } 24 | virtual void SetHandle(HWND hWnd) { this->m_hWnd = hWnd; } 25 | virtual void Keyboard(unsigned char c, int x, int y) 26 | { 27 | (void) x; (void) y; 28 | 29 | if (c == 'q' || c == 'Q') { PostQuitMessage(0); } 30 | } 31 | virtual void StartIdle(void) { GDIWMStartIdle(this); } 32 | virtual void StopIdle(void) { GDIWMStopIdle(this); } 33 | virtual void PostRedisplay(void) { InvalidateRect(m_hWnd, NULL, FALSE); } 34 | virtual LRESULT Default(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 35 | { 36 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 37 | } 38 | protected: 39 | HWND m_hWnd; 40 | }; 41 | 42 | #endif // GDIWINDOW_H 43 | -------------------------------------------------------------------------------- /src/TootleLib/gdiwm.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef GDIWM_H 7 | #define GDIWM_H 8 | /* -------------------------------------------------------------------------*\ 9 | * This is an abstraction that simplifies window management. 10 | * Instead of implementing a window procedure, we implement the interface 11 | * found in "gdiwindow.h", which is arguably much nicer. 12 | \* -------------------------------------------------------------------------*/ 13 | #include 14 | 15 | // forward declaration of window class 16 | class GDIWindow; 17 | 18 | /* -------------------------------------------------------------------------*\ 19 | * Initializes module. 20 | \* -------------------------------------------------------------------------*/ 21 | int GDIWMOpen(void); 22 | 23 | /* -------------------------------------------------------------------------*\ 24 | * Deinitializes module. 25 | \* -------------------------------------------------------------------------*/ 26 | int GDIWMClose(void); 27 | 28 | /* -------------------------------------------------------------------------*\ 29 | * Creates and shows new window with title "pszName" and whose controlling 30 | * object instance is given by the pointer "window". 31 | \* -------------------------------------------------------------------------*/ 32 | HWND GDIWMCreateWindow(const char* pszName, GDIWindow* window); 33 | 34 | /* -------------------------------------------------------------------------*\ 35 | * Destroy window controled by the object instance pointer "window". 36 | \* -------------------------------------------------------------------------*/ 37 | int GDIWMDestroyWindow(GDIWindow* window); 38 | 39 | /* -------------------------------------------------------------------------*\ 40 | * Causes a window to start receiving calls to its Window::Idle method 41 | * whenever the system is not processing other messages. 42 | \* -------------------------------------------------------------------------*/ 43 | int GDIWMStartIdle(GDIWindow* window); 44 | 45 | /* -------------------------------------------------------------------------*\ 46 | * Prevents a window from receiving idle calls. 47 | \* -------------------------------------------------------------------------*/ 48 | int GDIWMStopIdle(GDIWindow* window); 49 | 50 | /* -------------------------------------------------------------------------*\ 51 | * Changes the size of a window. 52 | \* -------------------------------------------------------------------------*/ 53 | void GDIWMResizeWindow(GDIWindow* window, int nWidth, int nHeight); 54 | 55 | /* -------------------------------------------------------------------------*\ 56 | * Starts the message loop. This function blocks until one of the windows 57 | * posts a QUIT message. 58 | \* -------------------------------------------------------------------------*/ 59 | void GDIWMMainLoop(void); 60 | 61 | /* -------------------------------------------------------------------------*\ 62 | * Add a dialog box to the message processing loop. 63 | \* -------------------------------------------------------------------------*/ 64 | int GDIWMAddDialog(HWND hDlg); 65 | 66 | /* -------------------------------------------------------------------------*\ 67 | * Window procedure used by windows created with GDIWMCreate window. 68 | \* -------------------------------------------------------------------------*/ 69 | LRESULT CALLBACK GDIMsgProc(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam); 70 | 71 | #endif // GDIWM_H 72 | -------------------------------------------------------------------------------- /src/TootleLib/heap.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef HEAP_H 7 | #define HEAP_H 8 | 9 | /* include file for module heap.c */ 10 | 11 | typedef struct _t_heap* p_heap; 12 | typedef int t_heap_cost; 13 | typedef size_t t_heap_key; 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | int heap_create(p_heap* H, t_heap_key _max); 20 | int heap_destroy(p_heap* H); 21 | t_heap_key heap_size(p_heap* H); 22 | int heap_insert(p_heap* H, t_heap_key key, t_heap_cost cost); 23 | t_heap_key heap_pop(p_heap* H, t_heap_cost* cost); 24 | int heap_remove(p_heap* H, t_heap_key key); 25 | t_heap_key heap_gettop(p_heap* H, t_heap_cost* cost); 26 | t_heap_key heap_size(p_heap* H); 27 | int heap_update(p_heap* H, t_heap_key key, t_heap_cost cost); 28 | t_heap_key heap_position(p_heap* H, t_heap_key key); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/TootleLib/makefile: -------------------------------------------------------------------------------- 1 | CC = g++ -fpermissive -msse -D_SOFTWARE_ONLY_VERSION -D_LINUX 2 | 3 | TOOTLETARGET = libTootle.a 4 | OPTIMIZE = -O3 -DNDEBUG 5 | 6 | TOP = ../.. 7 | TARGET = ${TOP}/lib/${TOOTLETARGET} 8 | RAYTRACER = RayTracer 9 | RTJRT = ${RAYTRACER}/JRT 10 | RTMATH = ${RAYTRACER}/Math 11 | 12 | CFLAGS = ${OPTIMIZE} -I. -Iinclude -I${RAYTRACER} -I${RTJRT} -I${RTMATH} 13 | 14 | OBJECTS = aligned_malloc.o clustering.o feedback.o fit.o overdraw.o soup.o souptomesh.o Stripifier.o Timer.o tootlelib.o triorder.o error.o heap.o ${RAYTRACER}/TootleRaytracer.o ${RTJRT}/JRTBoundingBox.o ${RTJRT}/JRTCamera.o ${RTJRT}/JRTCore.o ${RTJRT}/JRTCoreUtils.o ${RTJRT}/JRTH2KDTreeBuilder.o ${RTJRT}/JRTHeuristicKDTreeBuilder.o ${RTJRT}/JRTKDTree.o ${RTJRT}/JRTKDTreeBuilder.o ${RTJRT}/JRTMesh.o ${RTJRT}/JRTOrthoCamera.o ${RTJRT}/JRTPPMImage.o ${RTJRT}/JRTTriangleIntersection.o ${RTMATH}/JMLFuncs.o 15 | 16 | CLEAN = ${OBJECTS} *.o 17 | 18 | tootlelib: ${OBJECTS} 19 | ar -rs ${TARGET} *.o 20 | 21 | debug: 22 | ${MAKE} "OPTIMIZE=-g" "TOOTLETARGET=libTootle_d.a" 23 | 24 | .cpp.o: 25 | ${CC} ${CFLAGS} -c $< 26 | 27 | .c.o: 28 | ${CC} ${CFLAGS} -c $< 29 | 30 | clean: 31 | /bin/rm -f ${CLEAN} 32 | -------------------------------------------------------------------------------- /src/TootleLib/mesh.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef MESH_H 7 | #define MESH_H 8 | 9 | #include "soup.h" 10 | #include "Timer.h" 11 | #include "error.h" 12 | 13 | typedef std::vector< std::vector > VTArray; 14 | 15 | class Mesh: public Soup 16 | { 17 | public: 18 | Mesh(void) { ; } 19 | virtual ~Mesh() { ; } 20 | int ComputeVT(VTArray& vtOut); 21 | int ComputeAE(const VTArray& vt); 22 | int ComputeVV(void); 23 | 24 | 25 | // across-edge information 26 | std::vector& ae(int i) { return ae_[i]; } 27 | const std::vector& ae(int i) const { return ae_[i]; } 28 | std::vector< std::vector >& ae(void) { return ae_; } 29 | const std::vector< std::vector >& ae(void) const { return ae_; } 30 | 31 | // neighbor vertex information 32 | std::vector& vv(int i) { return vv_[i]; } 33 | const std::vector& vv(int i) const { return vv_[i]; } 34 | std::vector< std::vector >& vv(void) { return vv_; } 35 | const std::vector< std::vector >& vv(void) const { return vv_; } 36 | 37 | protected: 38 | // across edge info (same as structure as a triangle) 39 | std::vector< std::vector > ae_; 40 | // vertex neighboring vertices 41 | std::vector< std::vector > vv_; 42 | private: 43 | // prevent catastrophic copies 44 | Mesh (const Mesh&); 45 | Mesh& operator=(const Mesh&); 46 | }; 47 | 48 | inline int 49 | Mesh::ComputeVV(void) 50 | { 51 | Timer time; 52 | debugf(("Finding vertex neighbors")); 53 | 54 | vv ().resize (v ().size ()); 55 | 56 | for (int i = 0; i < static_cast(t().size()); i++) 57 | { 58 | vv(t(i)[0]).push_back (t(i)[1]); 59 | vv(t(i)[1]).push_back (t(i)[0]); 60 | vv(t(i)[1]).push_back (t(i)[2]); 61 | vv(t(i)[2]).push_back (t(i)[1]); 62 | vv(t(i)[2]).push_back (t(i)[0]); 63 | vv(t(i)[0]).push_back (t(i)[2]); 64 | } 65 | 66 | debugf(("Done in %gs", time.GetElapsed())); 67 | return 1; 68 | } 69 | 70 | inline int 71 | Mesh::ComputeVT(VTArray& vtOut) 72 | { 73 | Timer time; 74 | debugf(("Finding vertex faces")); 75 | 76 | // get all faces that use each vertex 77 | vtOut.resize (v ().size ()); 78 | 79 | for (int f = 0; f < static_cast(t().size()); f++) 80 | { 81 | Soup::Triangle& face = t(f); 82 | 83 | for (int i = 0; i < 3; i++) 84 | { 85 | vtOut[face[i]].push_back (f); 86 | } 87 | } 88 | 89 | debugf(("Done in %gs", time.GetElapsed())); 90 | return 1; 91 | } 92 | 93 | 94 | inline int 95 | Mesh::ComputeAE(const VTArray& vt) 96 | { 97 | Timer time; 98 | debugf(("Finding across edge-info")); 99 | // clean across-edge info 100 | ae().resize(t().size()); 101 | 102 | // find across-edge info 103 | for (int f = 0; f < static_cast(t().size()); f++) 104 | { 105 | for (int i = 0; i < 3; i++) 106 | { 107 | int in = (i + 1) % 3; 108 | // get the vertices in edge 109 | int v = t(f)[i]; 110 | int vn = t(f)[in]; 111 | 112 | // for each face that use v 113 | for (int j = 0; j < static_cast(vt[v].size()); j++) 114 | { 115 | // check if face has vn too and is not f 116 | int af = vt[v][j]; 117 | 118 | if (af != f) 119 | { 120 | for (int k = 0; k < 3; k++) 121 | { 122 | if (t(af)[k] == vn) 123 | { 124 | ae(f).push_back(af); 125 | } 126 | } 127 | } 128 | } 129 | } 130 | } 131 | 132 | debugf(("Done in %gs", time.GetElapsed())); 133 | return 1; 134 | } 135 | 136 | #endif -------------------------------------------------------------------------------- /src/TootleLib/option.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef OPTION_H 7 | #define OPTION_H 8 | 9 | #include 10 | 11 | static inline int match(const char* opt, const char* lname) 12 | { 13 | while (*lname && *opt && *opt != '=') 14 | { 15 | if (*opt != *lname) { return 0; } 16 | 17 | opt++; lname++; 18 | } 19 | 20 | return !(*lname) && (!(*opt) || *opt == '='); 21 | } 22 | 23 | class Option 24 | { 25 | public: 26 | Option(void); 27 | void Reset(void); 28 | int GetIndex(void); 29 | typedef struct 30 | { 31 | int sname; 32 | const char* lname; 33 | } Definition; 34 | enum State 35 | { 36 | DONE, 37 | LONG, 38 | SHORT, 39 | ARG 40 | }; 41 | int Parse(int argc, char* argv[], const Definition* def); 42 | const char* GetArgument(int argc, char* argv[]); 43 | private: 44 | void Advance(int argc, char* argv[]); 45 | int index; 46 | const char* where; 47 | int state; 48 | }; 49 | 50 | Option::Option(void) 51 | { 52 | Reset(); 53 | } 54 | 55 | int 56 | Option:: 57 | GetIndex(void) 58 | { 59 | return index; 60 | } 61 | 62 | const char* 63 | Option:: 64 | GetArgument(int argc, char* argv[]) 65 | { 66 | Advance(argc, argv); 67 | const char* arg = where; 68 | where = NULL; 69 | return arg; 70 | } 71 | 72 | void 73 | Option:: 74 | Reset(void) 75 | { 76 | index = 1; 77 | where = NULL; 78 | state = DONE; 79 | } 80 | 81 | void 82 | Option:: 83 | Advance(int argc, char* argv[]) 84 | { 85 | if (!where || !(*where)) 86 | { 87 | if (index < argc) 88 | { 89 | where = argv[index++]; 90 | 91 | if (*where == '-') 92 | { 93 | where++; 94 | 95 | if (*where == '-') 96 | { 97 | where++; 98 | 99 | if (!(*where)) { state = DONE; } 100 | else { state = LONG; } 101 | } 102 | else { state = SHORT; } 103 | } 104 | else { state = ARG; } 105 | } 106 | else { state = DONE; } 107 | } 108 | } 109 | 110 | int 111 | Option:: 112 | Parse(int argc, char* argv[], const Definition* def) 113 | { 114 | // advance to next command line option if needed 115 | Advance(argc, argv); 116 | 117 | // move to next argument 118 | switch (state) 119 | { 120 | case SHORT: 121 | for (; def->sname; def++) 122 | { 123 | if (def->sname == *where) 124 | { 125 | where++; 126 | return def->sname; 127 | } 128 | } 129 | 130 | return '?'; 131 | 132 | case LONG: 133 | for (; def->lname; def++) 134 | { 135 | if (match(where, def->lname)) 136 | { 137 | where += strcspn(where, "=") + 1; 138 | return def->sname; 139 | } 140 | } 141 | 142 | return '?'; 143 | 144 | case ARG: 145 | return '?'; 146 | 147 | default: 148 | return -1; 149 | } 150 | } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /src/TootleLib/overdraw.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _TOOTLE_OVERDRAW_MODULE_H_ 7 | #define _TOOTLE_OVERDRAW_MODULE_H_ 8 | 9 | #include "tootlelib.h" 10 | #include "vector.h" 11 | #include "feedback.h" 12 | #include 13 | 14 | #define TOOTLE_RAYTRACE_IMAGE_SIZE 512 // the image size used to optimize and measure overdraw using ray tracing implementation 15 | 16 | class Soup; 17 | 18 | TootleResult ODInit(); 19 | 20 | /// Determines whether or not ODInit has been called 21 | bool ODIsInitialized(); 22 | 23 | TootleResult ODSetSoup(Soup* pSoup, TootleFaceWinding eWinding); 24 | 25 | TootleResult ODObjectOverdraw(const float* pViewpoints, unsigned int nViewpoints, float& fODAvg, float& fODMax); 26 | TootleResult ODObjectOverdrawRaytrace(const float* pfVB, 27 | const unsigned int* pnIB, 28 | unsigned int nVertices, 29 | unsigned int nFaces, 30 | const float* pViewpoints, 31 | unsigned int nViewpoints, 32 | bool bCullCCW, 33 | float& fAvgOD, 34 | float& fMaxOD); 35 | 36 | TootleResult ODOverdrawGraph(const float* pViewpoints, 37 | unsigned int nViewpoints, 38 | bool bCullCCW, 39 | const std::vector& rClusters, 40 | const std::vector& rClusterOut, 41 | std::vector& rGraphOut, 42 | TootleOverdrawOptimizer eOverdrawOptimizer); 43 | 44 | void ODCleanup(); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/TootleLib/quaternion.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef QUATERNION_H 7 | #define QUATERNION_H 8 | 9 | #include "scalar.h" 10 | #include "vector.h" 11 | 12 | class Quaternion 13 | { 14 | public: 15 | // build a quaternion from its components 16 | Quaternion(float x = 0, float y = 0, float z = 0, float w = 0) 17 | { 18 | v[0] = x; v[1] = y; v[2] = z; a = w; 19 | } 20 | // builds a unit quaternion from a rotation (OpenGL like rotation) 21 | Quaternion(float r, const Vector3& u) 22 | { 23 | r *= SCALAR_TORADIAN; 24 | float n = Norm(u); 25 | 26 | if (Zero(n)) { n = 1.0f; } 27 | 28 | float inv_n = 1.0f / n; 29 | float s = (float)sin(r / 2); 30 | v[0] = u[0] * s * inv_n; v[1] = u[1] * s * inv_n; v[2] = u[2] * s * inv_n; 31 | a = (float) cos(r / 2); 32 | } 33 | // builds a quaternion from a vector and a scalar 34 | Quaternion(const Vector3& v, float a) 35 | { 36 | this->v[0] = v[0]; this->v[1] = v[1]; this->v[2] = v[2]; this->a = a; 37 | } 38 | // makes sure a quaternion can be used as a vector 39 | operator Vector3() const 40 | { 41 | return v; 42 | } 43 | 44 | // Conjugate a quaternion 45 | Quaternion operator!() const 46 | { 47 | return Quaternion(-v, a); 48 | } 49 | 50 | Quaternion operator-() const 51 | { 52 | return Quaternion(-v[0], -v[1], -v[2], -a); 53 | } 54 | 55 | Quaternion operator*(const Quaternion& r) const 56 | { 57 | return Quaternion(a * r.v + v * r.a + Cross(v, r.v), a * r.a - Dot(v, r.v)); 58 | } 59 | 60 | Quaternion operator*(const float s) 61 | { 62 | return Quaternion(s * v[0], s * v[1], s * v[2], s * a); 63 | } 64 | 65 | Quaternion& operator*=(const Quaternion& r) 66 | { 67 | v = a * r.v + v * r.a + Cross(v, r.v); 68 | a = a * r.a - Dot(v, r.v); 69 | return *this; 70 | } 71 | 72 | float GetRotation(float* x, float* y, float* z) const 73 | { 74 | float inv_n = (float)(1.0 / sqrt(Norm2(v) + a * a)); 75 | *x = v[0] * inv_n; *y = v[1] * inv_n; *z = v[2] * inv_n; 76 | return (float)(SCALAR_TODEGREE * 2.0 * acos(a * inv_n)); 77 | } 78 | 79 | float GetRotation(Vector3* v) const 80 | { 81 | Vector3& u = *v; 82 | return GetRotation(&u[0], &u[1], &u[2]); 83 | } 84 | 85 | private: 86 | // quaternion split in scalar and vector part 87 | Vector3 v; 88 | float a; 89 | }; 90 | 91 | //======================================================================= 92 | // Auxiliar functions 93 | //======================================================================= 94 | inline Quaternion operator*(const float& a, const Quaternion& q) 95 | { 96 | return q * a; 97 | } 98 | 99 | #endif // QUATERNION_H 100 | 101 | -------------------------------------------------------------------------------- /src/TootleLib/scalar.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef SCALAR_H 7 | #define SCALAR_H 8 | 9 | #include 10 | #include 11 | 12 | #define SCALAR_MIN (-1e9f) 13 | #define SCALAR_MAX (1e9f) 14 | #define SCALAR_EPSILON (1.0f/SCALAR_MAX) 15 | #define SCALAR_PI (3.14159265358979323846264338327950288419716939937510582f) 16 | #define SCALAR_TODEGREE (180.0f/SCALAR_PI) 17 | #define SCALAR_TORADIAN (SCALAR_PI/180.0f) 18 | 19 | #ifndef MAX 20 | #define MAX(a, b) ((a > b) ? (a) : (b)) 21 | #endif 22 | 23 | #ifndef MIN 24 | #define MIN(a, b) ((a < b) ? (a) : (b)) 25 | #endif 26 | 27 | template 28 | static inline void Swap(T& a, T& b) 29 | { 30 | T temp = a; 31 | a = b; 32 | b = temp; 33 | } 34 | 35 | template 36 | inline bool Zero(const T& a) 37 | { 38 | return fabs(a) <= (T)(SCALAR_EPSILON); 39 | } 40 | 41 | template 42 | inline bool Equal(const T& a, const U& b) 43 | { 44 | return Zero(a - b); 45 | } 46 | 47 | template 48 | inline bool Positive(const T& a) 49 | { 50 | return a > (T) SCALAR_EPSILON; 51 | } 52 | 53 | template 54 | inline bool Negative(const T& a) 55 | { 56 | return a < (T)(-SCALAR_EPSILON); 57 | } 58 | 59 | typedef unsigned char Uchar; 60 | typedef unsigned short Ushort; 61 | typedef unsigned long Ulong; 62 | 63 | inline double Limit(const Uchar& c) { (void) c; return UCHAR_MAX; } 64 | inline double Limit(const Ushort& c) { (void) c; return USHRT_MAX; } 65 | inline double Limit(const Ulong& c) { (void) c; return ULONG_MAX; } 66 | inline double Limit(const float& c) { (void) c; return 1.0; } 67 | inline double Limit(const double& c) { (void) c; return 1.0; } 68 | 69 | template 70 | inline void Translate(T& dest, const U& source) 71 | { dest = (T)(source * Limit(dest) / Limit(source)); } 72 | 73 | // optimizations 74 | inline void Translate(Uchar& dest, const Ushort& source) 75 | { dest = source >> 8; } 76 | inline void Translate(Ushort& dest, const Uchar& source) 77 | { dest = source << 8; } 78 | 79 | inline void Translate(float& dest, const Ushort& source) 80 | { dest = source * (1.0f / USHRT_MAX); } ; 81 | 82 | inline void Translate(float& dest, const Uchar& source) 83 | { dest = source * (1.0f / UCHAR_MAX); } ; 84 | 85 | template 86 | inline void Solve(const V& a, const V& b, const V& c, V* x1, V* x2) 87 | { 88 | V sd = sqrt(b * b - 4 * a * c); 89 | *x1 = (-b + sd) / (2 * a); 90 | *x2 = (-b - sd) / (2 * a); 91 | } 92 | 93 | #endif // SCALAR_H 94 | -------------------------------------------------------------------------------- /src/TootleLib/soup.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include 8 | #include "soup.h" 9 | #include "error.h" 10 | 11 | int 12 | Soup:: 13 | ComputeNormals(bool force) 14 | { 15 | debugf(("Computing normals")); 16 | 17 | if (n().size() == v().size() && !force) { return 1; } 18 | 19 | n ().resize (v ().size ()); 20 | 21 | const int nf = static_cast (t ().size ()); 22 | const int nv = static_cast (v ().size ()); 23 | 24 | for (int i = 0; i < nv; i++) 25 | { 26 | n(i) = Vector3(0, 0, 0); 27 | } 28 | 29 | for (int i = 0; i < nf; i++) 30 | { 31 | const Vector3& p0 = v(t(i)[0]); 32 | const Vector3& p1 = v(t(i)[1]); 33 | const Vector3& p2 = v(t(i)[2]); 34 | Vector3 a = p0 - p1, b = p1 - p2, c = p2 - p0; 35 | Vector3 tn = Cross(a, b); 36 | n(t(i)[0]) += tn; 37 | n(t(i)[1]) += tn; 38 | n(t(i)[2]) += tn; 39 | } 40 | 41 | for (int i = 0; i < nv; i++) 42 | { 43 | Normalize(n(i)); 44 | } 45 | 46 | debugf(("Done with normals")); 47 | return 1; 48 | } 49 | 50 | int 51 | Soup:: 52 | ComputeResolution(float* resolution, bool force) 53 | { 54 | const int nf = static_cast (t().size()); 55 | 56 | if (nf < 1 || r > 0.0 && !force) 57 | { 58 | *resolution = r; 59 | return 1; 60 | } 61 | 62 | int nsamp = nf / 2; 63 | 64 | if (nsamp > 333) { nsamp = 333; } 65 | 66 | std::vector samples; 67 | 68 | samples.reserve (nsamp * 3); 69 | 70 | for (int i = 0; i < nsamp; i++) 71 | { 72 | // Quick 'n dirty portable random number generator 73 | static unsigned randq = 0; 74 | randq = unsigned(1664525) * randq + unsigned(1013904223); 75 | int j = randq % nf; 76 | const Vector3& v0 = v(t(j)[0]); 77 | const Vector3& v1 = v(t(j)[1]); 78 | const Vector3& v2 = v(t(j)[2]); 79 | samples[3 * i + 0] = Norm2(v0 - v1); 80 | samples[3 * i + 1] = Norm2(v1 - v2); 81 | samples[3 * i + 2] = Norm2(v2 - v0); 82 | } 83 | 84 | nth_element(samples.begin(), 85 | samples.begin() + samples.size() / 2, 86 | samples.end()); 87 | *resolution = r = (float) sqrt(samples[samples.size() / 2]); 88 | return 1; 89 | } 90 | 91 | int 92 | Soup:: 93 | ComputeTriNormals(std::vector& tn) 94 | { 95 | debugf(("Computing tri normals")); 96 | 97 | tn.resize (t ().size ()); 98 | 99 | const int nf = static_cast (t().size()); 100 | 101 | for (int i = 0; i < nf; i++) 102 | { 103 | const Vector3& p0 = v(t(i)[0]); 104 | const Vector3& p1 = v(t(i)[1]); 105 | const Vector3& p2 = v(t(i)[2]); 106 | Vector3 a = p0 - p1, b = p1 - p2, c = p2 - p0; 107 | tn[i] = Normalize(Cross(a, b)); 108 | } 109 | 110 | debugf(("Done with tri normals")); 111 | return 1; 112 | } 113 | 114 | int 115 | Soup:: 116 | ComputeTriCenters(std::vector& tc) 117 | { 118 | debugf(("Computing tri centers")); 119 | 120 | tc.resize (t ().size ()); 121 | 122 | const int nf = static_cast (t().size()); 123 | 124 | for (int i = 0; i < nf; i++) 125 | { 126 | const Vector3& p0 = v(t(i)[0]); 127 | const Vector3& p1 = v(t(i)[1]); 128 | const Vector3& p2 = v(t(i)[2]); 129 | tc[i] = (p0 + p1 + p2) / 3.f; 130 | } 131 | 132 | debugf(("Done with tri centers")); 133 | return 1; 134 | } 135 | 136 | 137 | //================================================================================================================================= 138 | /// Constructs a 'soup' object from a vertex/index buffer. 139 | /// \param pVB The vertex buffer 140 | /// \param pIB The index buffer 141 | /// \param nVertices The number of vertices 142 | /// \param nFaces The number of faces 143 | /// \param nVBStride The stride of the vertex buffer 144 | /// \param pSoup The soup to initialize 145 | //================================================================================================================================= 146 | 147 | bool MakeSoup(const void* pVB, const unsigned int* pIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, Soup* pSoup) 148 | { 149 | pSoup->v ().resize (nVertices); 150 | pSoup->t ().resize (nFaces); 151 | 152 | // note that this code memcpy's from unsigned int to int. 153 | // This is ok since we have restricted the number of vertices and faces to be <= the largest signed integer 154 | // I would like to do it right, but it's problematic, because the adjacency and clustering code uses -1 as a sentinel all over the place 155 | memcpy(&(pSoup->t(0)[0]), pIB, sizeof(UINT) * 3 * nFaces); 156 | 157 | const char* pVBuffer = (const char*) pVB; 158 | 159 | for (unsigned int i = 0; i < nVertices; i++) 160 | { 161 | memcpy(&(pSoup->v(i)[0]), pVBuffer, sizeof(float) * 3); 162 | pVBuffer += nVBStride; 163 | } 164 | 165 | return true; 166 | } -------------------------------------------------------------------------------- /src/TootleLib/soup.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef SOUP_H 7 | #define SOUP_H 8 | 9 | #include "cloud.h" 10 | 11 | typedef unsigned int UINT; 12 | 13 | class Soup: public Cloud 14 | { 15 | public: 16 | 17 | Soup(void) 18 | { 19 | r = -1; 20 | } 21 | 22 | virtual ~Soup() 23 | { 24 | } 25 | 26 | 27 | class Triangle 28 | { 29 | public: 30 | Triangle(int i0 = 0, int i1 = 0, int i2 = 0) 31 | { 32 | vi[0] = i0; vi[1] = i1; vi[2] = i2; 33 | } 34 | const int& operator[](int c) const { return vi[c]; } 35 | int& operator[](int c) { return vi[c]; } 36 | const int& i(int c) const { return vi[c]; } 37 | int& i(int c) { return vi[c]; } 38 | int* i(void) { return vi; } 39 | private: 40 | int vi[3]; 41 | }; 42 | 43 | Triangle& t(size_t i) { return pt[i]; } 44 | const Triangle& t(size_t i) const { return pt[i]; } 45 | std::vector& t(void) { return pt; } 46 | const std::vector& t(void) const { return pt; } 47 | void t(const std::vector& new_t) 48 | { 49 | pt = new_t; 50 | } 51 | 52 | int ComputeNormals(bool force = false); 53 | int ComputeTriNormals(std::vector& tn); 54 | int ComputeTriCenters(std::vector& tc); 55 | int ComputeResolution(float* resolution, bool force = false); 56 | 57 | protected: 58 | float r; 59 | std::vector pt; 60 | 61 | private: 62 | Soup (const Soup&); 63 | Soup& operator=(const Soup&); 64 | 65 | }; 66 | 67 | /// Helper function which creates a soup from a vertex and index buffer 68 | bool MakeSoup(const void* pVB, const unsigned int* pIB, unsigned int nVertices, unsigned int nFaces, unsigned int nVBStride, Soup* pSoup); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/TootleLib/souptomesh.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include "TootlePCH.h" 7 | #include "souptomesh.h" 8 | 9 | int SoupToMesh(Soup* soup, Mesh* mesh) 10 | { 11 | 12 | if (soup->v().size() > 0) { mesh->v(soup->v()); } 13 | 14 | if (soup->n().size() > 0) { mesh->n(soup->n()); } 15 | 16 | if (soup->c().size() > 0) { mesh->c(soup->c()); } 17 | 18 | if (soup->vc().size() > 0) { mesh->vc(soup->vc()); } 19 | 20 | if (soup->t().size() > 0) { mesh->t(soup->t()); } 21 | 22 | mesh->ae().resize(0); 23 | mesh->vv().resize(0); 24 | return 1; 25 | } -------------------------------------------------------------------------------- /src/TootleLib/souptomesh.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef SOUPTOMESH_H 7 | #define SOUPTOMESH_H 8 | 9 | #include "mesh.h" 10 | #include "soup.h" 11 | 12 | int SoupToMesh(Soup* soup, Mesh* mesh); 13 | 14 | #endif -------------------------------------------------------------------------------- /src/TootleLib/triorder.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _TRIORDER_H 7 | #define _TRIORDER_H 8 | 9 | #define TOOTLE_NONE (2147483647) // 2^31 -1 (ideally should be 2^32-1 for max unsigned int). However, int and 10 | // unsigned int are used interchangebly in the library. 11 | 12 | /// Perform vertex optimization only 13 | float FanVertOptimizeVCacheOnly(int* piIndexBufferIn, 14 | int* piIndexBufferOut, 15 | int iNumVertices, 16 | int iNumFaces, 17 | int iCacheSize, 18 | int* piScratch = NULL, 19 | int* piClustersOut = NULL, 20 | int* iNumClusters = NULL); 21 | 22 | /// The function below just clusters the mesh. It assumes it is already sorted and pre-clustered 23 | /// with "hard boundaries" during vertex cache optimization using the above function. 24 | /// (please see paper for more details) 25 | void FanVertOptimizeClusterOnly(int* piIndexBufferIn, 26 | int iNumVertices, 27 | int iNumFaces, 28 | int iCacheSize, 29 | float lambda, 30 | int* piClustersIn, 31 | int iNumClusters, 32 | int* piClustersOut, 33 | int* iNumClustersOut, 34 | int* piScratch = NULL); 35 | 36 | // The function below just optimizes for overdraw and returns a "remap" array which maps the new cluster IDs to 37 | // the old ones. It is particularly useful for characters composed of multiple draw calls, as this will give an ordering 38 | // of draw calls to attempt to reduce overdraw. 39 | void FanVertOptimizeOverdrawOnly(float* pfVertexPositionsIn, 40 | int* piIndexBufferIn, 41 | int* piIndexBufferOut, 42 | int iNumVertices, 43 | int iNumFaces, 44 | TootleFaceWinding eFrontWinding, 45 | int* piClustersIn, 46 | int iNumClusters, 47 | int* piScratch = NULL, 48 | int* piRemap = NULL); 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/TootleLib/vector.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef VECTOR_H 7 | #define VECTOR_H 8 | 9 | #include 10 | #include "matrix.h" 11 | 12 | // A vector is just a matrix with one column 13 | // I wanted to use partial template specialization, 14 | // but my compiler doesn't like it :o( 15 | 16 | // shorthand declarations 17 | typedef Matrix<2, 1, float> Vector2; 18 | typedef Matrix<3, 1, float> Vector3; 19 | typedef Matrix<4, 1, float> Vector4; 20 | typedef Matrix<5, 1, float> Vector5; 21 | typedef Matrix<6, 1, float> Vector6; 22 | typedef Matrix<7, 1, float> Vector7; 23 | typedef Matrix<8, 1, float> Vector8; 24 | typedef Matrix<9, 1, float> Vector9; 25 | 26 | template 27 | inline Matrix<3, 1, V> Cross(const Matrix<3, 1, V>& u, const Matrix<3, 1, V>& v) 28 | { 29 | return Matrix<3, 1, V>(u[1] * v[2] - u[2] * v[1], 30 | u[2] * v[0] - u[0] * v[2], 31 | u[0] * v[1] - u[1] * v[0]); 32 | } 33 | 34 | template 35 | inline V Dot(const Matrix& u, const Matrix& v) 36 | { 37 | float s = 0; 38 | 39 | for (int i = 0; i < M; i++) 40 | { 41 | s += u[i] * v[i]; 42 | } 43 | 44 | return s; 45 | } 46 | 47 | template 48 | inline V Norm2(const Matrix& v) 49 | { 50 | return Dot(v, v); 51 | } 52 | 53 | template 54 | inline Matrix& Normalize(Matrix& v) 55 | { 56 | v /= Norm(v); 57 | return v; 58 | } 59 | 60 | template 61 | inline Matrix Normalize(const Matrix& v) 62 | { 63 | Matrix u = v; 64 | u /= Norm(u); 65 | return u; 66 | } 67 | 68 | template 69 | inline V Norm(const Matrix& v) 70 | { 71 | return sqrt(Norm2(v)); 72 | } 73 | 74 | template 75 | inline V Phase(const Matrix& v) 76 | { 77 | return atan2(v[1], v[0]); 78 | } 79 | 80 | template 81 | inline Matrix Outer(const Matrix& a, const Matrix& b) 82 | { 83 | int i, j; 84 | Matrix r; 85 | 86 | for (i = 0; i < N; i++) 87 | for (j = i; j < N; j++) 88 | { 89 | r(i, j) = a(i) * b(j); 90 | } 91 | 92 | for (i = 0; i < N; i++) 93 | for (j = 0; j < i; j++) 94 | { 95 | r(i, j) = r(j, i); 96 | } 97 | 98 | return r; 99 | } 100 | 101 | template 102 | inline Matrix<3, 3, V> Cross(const Matrix<3, 1, V>& t) 103 | { 104 | V r[] = {0, -t[2], t[1], t[2], 0, -t[0], -t[1], t[0], 0}; 105 | return Matrix<3, 3, V>(r); 106 | } 107 | 108 | template 109 | inline Matrix<3, 3, V> Rodrigues(const Matrix<3, 1, V>& w) 110 | { 111 | V a = Norm(w); 112 | Matrix3 I = Identity<3, V>(); 113 | 114 | if (Zero(a)) { return I; } 115 | 116 | Vector3 n = w / a; 117 | V c = (V) cos(a); 118 | V s = (V) sin(a); 119 | return c * I + (I - c * I) * Outer(n, n) + s * Cross(n); 120 | } 121 | 122 | #endif // VECTOR_H 123 | -------------------------------------------------------------------------------- /src/TootleLib/window.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef WINDOW_H 7 | #define WINDOW_H 8 | /* -------------------------------------------------------------------------*\ 9 | * This is an abstraction over a window canvas. 10 | \* -------------------------------------------------------------------------*/ 11 | 12 | // mouse buttons 13 | enum {M_LEFT, M_MIDDLE, M_RIGHT}; 14 | // button state 15 | enum {M_UP, M_DOWN, M_DOUBLE}; 16 | // modifiers 17 | enum {M_NORMAL, M_CONTROL, M_SHIFT}; 18 | 19 | class Window 20 | { 21 | public: 22 | Window() { w = 0; h = 0; } 23 | virtual ~Window(void) { ; } 24 | // Callbacks 25 | // Called uppon window creation 26 | virtual int Create(void) { return 1; } 27 | // Called uppon window destruction 28 | virtual void Destroy(void) { ; } 29 | // Called when canvas need redraw 30 | virtual int Display(void) { return 1; } 31 | // Called when computer is idle. 32 | virtual void Idle(void) { ; } 33 | // Called when canvas is reshaped. 34 | virtual void Reshape(int w, int h) { this->w = w; this->h = h; } 35 | // called when mouse moves 36 | virtual void Motion(int x, int y, int modifier) 37 | { (void) x; (void) y; (void) modifier; } 38 | // Called when mouse button is pressed or released 39 | virtual void Button(int button, int state, int x, int y, int modifier) 40 | { (void) button; (void) state; (void) x; (void) y; } 41 | // Called when key is pressed 42 | virtual void Keyboard(unsigned char c, int x, int y) 43 | { (void) c; (void) x; (void) y; } 44 | virtual int GetWidth(void) { return w; } 45 | virtual int GetHeight(void) { return h; } 46 | private: 47 | int w, h; 48 | }; 49 | 50 | #endif // WINDOW_H 51 | -------------------------------------------------------------------------------- /src/TootleSample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(TootleSample) 2 | 3 | SET(SOURCES 4 | MaterialSort.cpp 5 | ObjLoader.cpp 6 | Timer.cpp 7 | Tootle.cpp) 8 | 9 | SET(HEADERS 10 | ObjLoader.h 11 | option.h 12 | Timer.h) 13 | 14 | ADD_EXECUTABLE(TootleSample ${SOURCES} ${HEADERS}) 15 | TARGET_LINK_LIBRARIES(TootleSample TootleLib) 16 | -------------------------------------------------------------------------------- /src/TootleSample/MaterialSort.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #include 7 | #include 8 | #include "tootlelib.h" 9 | 10 | typedef unsigned int UINT; 11 | 12 | //================================================================================================================================= 13 | /// A utility function to sort the materials in a mesh to minimize overdraw, without optimizing within materials. This kind of 14 | /// optimization can be very effective by itself, or it can be combined with inter-material optimization for even better results. 15 | /// This function is currently not used in the sample, it is provided for illustrative purposes only. 16 | /// 17 | /// - pTriMaterialIDs is an array containing a material index for each triangle 18 | /// - nMaterials is the number of materials in the mesh 19 | /// 20 | /// The triangles are assumed to be sorted by material, meaning that pTriMaterialIDs contains 00000...1111....2222.... and so on... 21 | /// 22 | /// \param pfVB A pointer to the vertex buffer. The pointer pVB must point to the vertex position. The vertex 23 | /// position must be a 3-component floating point value (X,Y,Z). 24 | /// \param pnIB The mesh index buffer. This must be a triangle list. The faces must be clustered 25 | /// \param nVertices The number of vertices in the mesh. This must be non-zero and less than TOOTLE_MAX_VERTICES. 26 | /// \param nFaces The number of faces in the mesh. This must be non-zero and less than TOOTLE_MAX_FACES. 27 | /// \param nVBStride The distance between successive vertices in the vertex buffer, in bytes. This must be at least 28 | /// 3*sizeof(float)./// \param pnIB 29 | /// \param pnTriMaterialIDs An array containing a material index for each triangle. 30 | /// \param nMaterials the number of materials in the mesh. 31 | /// 32 | /// \return An array containing the new material order. Element 0 in this array contains the ID of the 33 | /// material that should be drawn first, element 1 contains the second, element 2 contains the third, and so on. 34 | //================================================================================================================================= 35 | UINT* SortMaterials(const float* pfVB, 36 | const UINT* pnIB, 37 | UINT nVertices, 38 | UINT nVBStride, 39 | UINT nFaces, 40 | UINT* pnTriMaterialIDs, 41 | UINT nMaterials) 42 | { 43 | // make an array to hold the material re-mapping 44 | UINT* pnMaterialRemap = new UINT [ nMaterials ]; 45 | 46 | // optimize the draw order 47 | TootleResult result = TootleOptimizeOverdraw(pfVB, pnIB, nVertices, nFaces, nVBStride, 48 | NULL, 0, // use default viewpoints 49 | TOOTLE_CCW, 50 | pnTriMaterialIDs, // cluster IDs == material ID 51 | NULL, // do not care about re-mapped index buffer 52 | pnMaterialRemap); 53 | 54 | if (result != TOOTLE_OK) 55 | { 56 | return NULL; // uh-oh 57 | } 58 | 59 | 60 | return pnMaterialRemap; 61 | } 62 | -------------------------------------------------------------------------------- /src/TootleSample/ObjLoader.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | 7 | #ifndef _OBJLOADER_H_ 8 | #define _OBJLOADER_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | //..............................................................................................................// 15 | //..............................................................................................................// 16 | //..............................................................................................................// 17 | // OBJ File structure 18 | //..............................................................................................................// 19 | //..............................................................................................................// 20 | //..............................................................................................................// 21 | 22 | // 3D Vector ( for position and normals ) 23 | struct ObjVertex3D 24 | { 25 | float x; 26 | float y; 27 | float z; 28 | }; // End of ObjVertex3D 29 | 30 | 31 | // 2D Vector ( for texture coordinates ) 32 | struct ObjVertex2D 33 | { 34 | float x; 35 | float y; 36 | }; // End of ObjVertex2D 37 | 38 | 39 | // Final Vertex Structure 40 | struct ObjVertexFinal 41 | { 42 | ObjVertexFinal() 43 | { 44 | pos.x = 0.0f; 45 | pos.y = 0.0f; 46 | pos.z = 0.0f; 47 | 48 | normal.x = 0.0f; 49 | normal.y = 0.0f; 50 | normal.z = 0.0f; 51 | 52 | texCoord.x = 0.0f; 53 | texCoord.y = 0.0f; 54 | }; // End of Constructor 55 | 56 | ObjVertex3D pos; 57 | ObjVertex3D normal; 58 | ObjVertex2D texCoord; 59 | 60 | // indices of vertex, normal, and texcoord that make up this vertex 61 | unsigned int nVertexIndex; 62 | unsigned int nNormalIndex; 63 | unsigned int nTexcoordIndex; 64 | 65 | }; // End of ObjVertexFinal 66 | 67 | 68 | // Face 69 | struct ObjFace 70 | { 71 | ObjFace() 72 | { 73 | int i; 74 | 75 | for (i = 0; i < 3; i++) 76 | { 77 | vertexIndices[i] = 0; 78 | texCoordIndices[i] = 0; 79 | normalIndices[i] = 0; 80 | 81 | finalVertexIndices[i] = 0; 82 | } // End for 83 | }; // End of ObjFace 84 | 85 | unsigned int vertexIndices[3]; 86 | unsigned int texCoordIndices[3]; 87 | unsigned int normalIndices[3]; 88 | 89 | // This is the index used to for rendering 90 | unsigned int finalVertexIndices[3]; 91 | }; // End of ObjFace 92 | 93 | 94 | 95 | 96 | //================================================================================================================================= 97 | /// \brief An OBJ file loader 98 | /// This OBJ loader supports a subset of the OBJ file format. In particular: 99 | /// - It supports only polygonal primitives 100 | /// - It does not support materials 101 | /// - It does not support texture coordinates with three channels 102 | /// 103 | //================================================================================================================================= 104 | class ObjLoader 105 | { 106 | public: 107 | 108 | /// Loads a mesh from a wavefront OBJ file 109 | bool LoadGeometry(const char* strFileName, std::vector& rVerticesOut, std::vector& rFacesOut); 110 | 111 | 112 | private: 113 | 114 | // VertexHashData 115 | struct VertexHashData 116 | { 117 | unsigned int vertexIndex; 118 | unsigned int texCoordIndex; 119 | unsigned int normalIndex; 120 | 121 | unsigned int finalIndex; 122 | }; // End of VertexHashData 123 | 124 | 125 | struct vertex_less : public std::less 126 | { 127 | bool operator()(const VertexHashData& x, const VertexHashData& y) const 128 | { 129 | if (x.vertexIndex < y.vertexIndex) 130 | { 131 | return true; 132 | } 133 | 134 | if (x.vertexIndex > y.vertexIndex) 135 | { 136 | return false; 137 | } 138 | 139 | if (x.texCoordIndex < y.texCoordIndex) 140 | { 141 | return true; 142 | } 143 | 144 | if (x.texCoordIndex > y.texCoordIndex) 145 | { 146 | return false; 147 | } 148 | 149 | if (x.normalIndex < y.normalIndex) 150 | { 151 | return true; 152 | } 153 | 154 | if (x.normalIndex > y.normalIndex) 155 | { 156 | return false; 157 | } 158 | 159 | return false; 160 | }; // End of operator() 161 | }; // End of vertex_less 162 | 163 | 164 | bool BuildModel(const std::vector& vertices, 165 | const std::vector& normals, 166 | const std::vector& texCoords, 167 | std::vector& finalVertices, 168 | std::vector& faces); 169 | 170 | // Returns how many vertices are specified in one line read from OBJ 171 | int GetNumberOfVerticesInLine(const char* szLine); 172 | 173 | // Read vertex indices 174 | void ReadVertexIndices(const char* szLine, int numVertsInLine, 175 | bool bHasTexCoords, bool bHasNormals, 176 | int* pVertIndices, int* pTexCoords, int* pNormals); 177 | 178 | // Buildup vertex hash map 179 | void BuildFinalVertices(const std::vector& vertices, 180 | const std::vector& normals, 181 | const std::vector& texCoords, 182 | std::vector& faces, 183 | std::vector& finalVertices); 184 | 185 | }; 186 | 187 | 188 | #endif // _OBJLOADER_H_ 189 | -------------------------------------------------------------------------------- /src/TootleSample/Timer.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | //#include "TootlePCH.h" 7 | #ifdef _WIN32 8 | #include 9 | #else 10 | #include 11 | #include 12 | #endif 13 | 14 | #include "Timer.h" 15 | 16 | Timer:: 17 | Timer() 18 | { 19 | Reset(); 20 | } 21 | 22 | void 23 | Timer:: 24 | Reset(void) 25 | { 26 | time = Get(); 27 | } 28 | 29 | double 30 | Timer:: 31 | GetElapsed(void) 32 | { 33 | return Get() - time; 34 | } 35 | 36 | double 37 | Timer::Get(void) 38 | { 39 | #ifdef _WIN32 40 | #if 0 41 | return GetTickCount(); 42 | #else 43 | FILETIME ft; 44 | GetSystemTimeAsFileTime(&ft); 45 | return ft.dwLowDateTime / 1.0e7 + ft.dwHighDateTime * (4294967296.0 / 1.0e7); 46 | #endif 47 | #else 48 | struct timeval v; 49 | gettimeofday(&v, (struct timezone*) NULL); 50 | return v.tv_sec + v.tv_usec / 1.0e6; 51 | #endif 52 | } 53 | -------------------------------------------------------------------------------- /src/TootleSample/Timer.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef _TIMER_H 7 | #define _TIMER_H 8 | 9 | class Timer 10 | { 11 | public: 12 | Timer(); 13 | void Reset(void); 14 | double GetElapsed(void); 15 | double Get(void); 16 | private: 17 | double time; 18 | }; 19 | 20 | #endif // _TIMER_H 21 | -------------------------------------------------------------------------------- /src/TootleSample/makefile: -------------------------------------------------------------------------------- 1 | CC = g++ -D_SOFTWARE_ONLY_VERSION -D_LINUX 2 | 3 | OPTIMIZE = -O3 -DNDEBUG 4 | 5 | TOOTLELIB = -lTootle 6 | 7 | TOOTLETARGET = TootleSample 8 | 9 | TOP = ../.. 10 | 11 | TARGET = ${TOP}/bin/${TOOTLETARGET} 12 | 13 | CFLAGS = ${OPTIMIZE} -I. -I${TOP}/src/TootleLib/include 14 | 15 | LDFLAGS = -L${TOP}/lib ${TOOTLELIB} -lm 16 | 17 | OBJECTS = Tootle.o ObjLoader.o MaterialSort.o Timer.o 18 | 19 | CLEAN = ${TARGET} ${OBJECTS} *.o 20 | 21 | Tootle: ${OBJECTS} 22 | ${CC} ${CFLAGS} -o ${TARGET} ${OBJECTS} ${LDFLAGS} 23 | 24 | debug: 25 | ${MAKE} "OPTIMIZE=-g" "TOOTLELIB=-lTootle_d" "TOOTLETARGET=Tootle_d" 26 | 27 | .cpp.o: 28 | ${CC} ${CFLAGS} -c $< 29 | 30 | clean: 31 | /bin/rm -f ${CLEAN} 32 | -------------------------------------------------------------------------------- /src/TootleSample/option.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************//** 2 | // Copyright (c) 2006-2015 Advanced Micro Devices, Inc. All rights reserved. 3 | /// \author AMD Developer Tools Team 4 | /// \file 5 | ****************************************************************************************/ 6 | #ifndef OPTION_H 7 | #define OPTION_H 8 | 9 | #include 10 | 11 | static inline int match(const char* opt, const char* lname) 12 | { 13 | while (*lname && *opt && *opt != '=') 14 | { 15 | if (*opt != *lname) { return 0; } 16 | 17 | opt++; lname++; 18 | } 19 | 20 | return !(*lname) && (!(*opt) || *opt == '='); 21 | } 22 | 23 | class Option 24 | { 25 | public: 26 | Option(void); 27 | void Reset(void); 28 | int GetIndex(void); 29 | typedef struct 30 | { 31 | int sname; 32 | const char* lname; 33 | } Definition; 34 | enum State 35 | { 36 | DONE, 37 | LONG, 38 | SHORT, 39 | ARG 40 | }; 41 | int Parse(int argc, char* argv[], const Definition* def); 42 | const char* GetArgument(int argc, char* argv[]); 43 | private: 44 | void Advance(int argc, char* argv[]); 45 | int index; 46 | const char* where; 47 | int state; 48 | }; 49 | 50 | Option::Option(void) 51 | { 52 | Reset(); 53 | } 54 | 55 | int 56 | Option:: 57 | GetIndex(void) 58 | { 59 | return index; 60 | } 61 | 62 | const char* 63 | Option:: 64 | GetArgument(int argc, char* argv[]) 65 | { 66 | Advance(argc, argv); 67 | const char* arg = where; 68 | where = NULL; 69 | return arg; 70 | } 71 | 72 | void 73 | Option:: 74 | Reset(void) 75 | { 76 | index = 1; 77 | where = NULL; 78 | state = DONE; 79 | } 80 | 81 | void 82 | Option:: 83 | Advance(int argc, char* argv[]) 84 | { 85 | if (!where || !(*where)) 86 | { 87 | if (index < argc) 88 | { 89 | where = argv[index++]; 90 | 91 | if (*where == '-') 92 | { 93 | where++; 94 | 95 | if (*where == '-') 96 | { 97 | where++; 98 | 99 | if (!(*where)) { state = DONE; } 100 | else { state = LONG; } 101 | } 102 | else { state = SHORT; } 103 | } 104 | else { state = ARG; } 105 | } 106 | else { state = DONE; } 107 | } 108 | } 109 | 110 | int 111 | Option:: 112 | Parse(int argc, char* argv[], const Definition* def) 113 | { 114 | // advance to next command line option if needed 115 | Advance(argc, argv); 116 | 117 | // move to next argument 118 | switch (state) 119 | { 120 | case SHORT: 121 | for (; def->sname; def++) 122 | { 123 | if (def->sname == *where) 124 | { 125 | where++; 126 | return def->sname; 127 | } 128 | } 129 | 130 | return '?'; 131 | 132 | case LONG: 133 | for (; def->lname; def++) 134 | { 135 | if (match(where, def->lname)) 136 | { 137 | where += strcspn(where, "=") + 1; 138 | return def->sname; 139 | } 140 | } 141 | 142 | return '?'; 143 | 144 | case ARG: 145 | return '?'; 146 | 147 | default: 148 | return -1; 149 | } 150 | } 151 | 152 | #endif 153 | --------------------------------------------------------------------------------