merge
3
.hgtags
|
@ -6,3 +6,6 @@ e3c0182ba64b77319ce84c9e2a8581649e68273d v0.2.1
|
|||
cb6e89af8012fac22cc0f3c5ad247c98c701bdda v0.3.0
|
||||
ee26517b27207353b0c8a7d357bcb4977b5d93fb v0.4.0
|
||||
7db07694ea00eb1655f7a1adcc3ae880e8e116f9 v0.4.1
|
||||
13a39b11aceee517c19d2e2cec2e6b875546062c v0.4.2
|
||||
f1b73d39617071297167cc7ce96f3892f21105fc v0.4.3
|
||||
bd6ddacdf7955e51d9b80be639c282d4974e6f56 v0.4.4
|
||||
|
|
|
@ -35,31 +35,26 @@ endif()
|
|||
|
||||
# Load the required modules
|
||||
include (MitsubaUtil)
|
||||
include (MtsGetVersionInfo)
|
||||
include (CheckCXXSourceCompiles)
|
||||
include (CMakeDependentOption)
|
||||
|
||||
# Read version (MTS_VERSION) from include/mitsuba/core/version.h
|
||||
file(STRINGS "include/mitsuba/core/version.h" MITSUBA_H REGEX "^#define MTS_VERSION \"[^\"]*\"$")
|
||||
string(REGEX REPLACE "^.*MTS_VERSION \"([0-9]+).*$" "\\1" MTS_VERSION_MAJOR "${MITSUBA_H}")
|
||||
string(REGEX REPLACE "^.*MTS_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" MTS_VERSION_MINOR "${MITSUBA_H}")
|
||||
string(REGEX REPLACE "^.*MTS_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" MTS_VERSION_PATCH "${MITSUBA_H}")
|
||||
set(MTS_VERSION "${MTS_VERSION_MAJOR}.${MTS_VERSION_MINOR}.${MTS_VERSION_PATCH}")
|
||||
set(MITSUBA_H)
|
||||
if("${MTS_VERSION_MAJOR}" MATCHES "[0-9]+" AND
|
||||
"${MTS_VERSION_MINOR}" MATCHES "[0-9]+" AND
|
||||
"${MTS_VERSION_PATCH}" MATCHES "[0-9]+")
|
||||
message(STATUS "mitsuba ${MTS_VERSION}")
|
||||
# Read the version information
|
||||
MTS_GET_VERSION_INFO()
|
||||
if (MTS_HAS_VALID_REV)
|
||||
message(STATUS "mitsuba ${MTS_VERSION}-hg${MTS_REV_ID} (${MTS_DATE})")
|
||||
else()
|
||||
message(FATAL_ERROR "The mitsuba version could not be determined!")
|
||||
message(STATUS "mitsuba ${MTS_VERSION} (${MTS_DATE})")
|
||||
endif()
|
||||
|
||||
# Setup the build options
|
||||
include (MitsubaBuildOptions)
|
||||
|
||||
# Find the external libraries and setup the paths
|
||||
include (MitsubaExternal)
|
||||
|
||||
# Setup the build options, include paths and compile definitions
|
||||
include (MitsubaBuildOptions)
|
||||
|
||||
# Main mitsuba include directory
|
||||
include_directories("include")
|
||||
|
||||
# ===== Prerequisite resources =====
|
||||
|
||||
|
@ -92,8 +87,13 @@ endif()
|
|||
# Additional files to add to main executables
|
||||
if(APPLE)
|
||||
set(MTS_DARWIN_STUB "${CMAKE_CURRENT_SOURCE_DIR}/src/mitsuba/darwin_stub.mm")
|
||||
set(MTS_WINDOWS_STUB "")
|
||||
elseif(WIN32)
|
||||
set(MTS_DARWIN_STUB "")
|
||||
set(MTS_WINDOWS_STUB "${CMAKE_CURRENT_SOURCE_DIR}/data/windows/wmain_stub.cpp")
|
||||
else()
|
||||
set(MTS_DARWIN_STUB "")
|
||||
set(MTS_WINDOWS_STUB "")
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ import os
|
|||
resources = []
|
||||
plugins = []
|
||||
stubs = []
|
||||
winstubs = []
|
||||
|
||||
Export('SCons', 'sys', 'os', 'glob', 'resources',
|
||||
'plugins', 'stubs')
|
||||
'plugins', 'stubs', 'winstubs')
|
||||
|
||||
# Configure the build framework
|
||||
env = SConscript('build/SConscript.configure')
|
||||
|
@ -18,6 +19,9 @@ Export('env')
|
|||
if sys.platform == 'win32':
|
||||
# Set an application icon on Windows
|
||||
resources += [ env.RES('data/windows/mitsuba_res.rc') ]
|
||||
# Convert the command line args from UTF-8 to UTF-16
|
||||
winstubs += [ env.SharedObject('#data/windows/wmain_stub.cpp') ]
|
||||
Export('winstubs')
|
||||
|
||||
def build(scriptFile, exports = [], duplicate = 0):
|
||||
dirname = '/'.join(os.path.dirname(scriptFile).split('/')[1:])
|
||||
|
|
|
@ -374,7 +374,7 @@ env.__class__.ConfigureForObjectiveCPP = configure_for_objective_cpp
|
|||
env.__class__.RelaxCompilerSettings = relax_compiler_settings
|
||||
|
||||
if hasCollada:
|
||||
env.Append(CPPDEFINES = [['MTS_HAS_COLLADA', 1]] )
|
||||
env.Append(CPPDEFINES = [['MTS_HAS_COLLADA', 1]])
|
||||
|
||||
env.SConsignFile()
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ GLLIB = ['GL', 'GLU', 'GLEWmx', 'Xxf86vm', 'X11']
|
|||
GLFLAGS = ['-DGLEW_MX']
|
||||
BOOSTLIB = ['boost_system', 'boost_filesystem', 'boost_thread']
|
||||
COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4']
|
||||
COLLADALIB = ['collada14dom']
|
||||
COLLADALIB = ['collada14dom', 'xml2']
|
||||
|
||||
# The following assumes that the Mitsuba bindings should be built for the
|
||||
# "default" Python version. It is also possible to build bindings for multiple
|
||||
|
|
|
@ -20,7 +20,7 @@ GLLIB = ['GL', 'GLU', 'GLEWmx', 'Xxf86vm', 'X11']
|
|||
GLFLAGS = ['-DGLEW_MX']
|
||||
BOOSTLIB = ['boost_system', 'boost_filesystem', 'boost_thread']
|
||||
COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4']
|
||||
COLLADALIB = ['collada14dom']
|
||||
COLLADALIB = ['collada14dom', 'xml2']
|
||||
|
||||
# The following assumes that the Mitsuba bindings should be built for the
|
||||
# "default" Python version. It is also possible to build bindings for multiple
|
||||
|
|
|
@ -20,7 +20,7 @@ GLLIB = ['GL', 'GLU', 'GLEWmx', 'Xxf86vm', 'X11']
|
|||
GLFLAGS = ['-DGLEW_MX']
|
||||
BOOSTLIB = ['boost_system', 'boost_filesystem', 'boost_thread']
|
||||
COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4']
|
||||
COLLADALIB = ['collada14dom']
|
||||
COLLADALIB = ['collada14dom', 'xml2']
|
||||
|
||||
# The following assumes that the Mitsuba bindings should be built for the
|
||||
# "default" Python version. It is also possible to build bindings for multiple
|
||||
|
|
|
@ -6,7 +6,7 @@ CCFLAGS = ['-arch', 'x86_64', '-mmacosx-version-min=10.7', '-march=nocona
|
|||
LINKFLAGS = ['-framework', 'OpenGL', '-framework', 'Cocoa', '-arch', 'x86_64', '-mmacosx-version-min=10.7', '-Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk', '-Wl,-headerpad,128']
|
||||
BASEINCLUDE = ['#include', '#dependencies/include']
|
||||
BASELIBDIR = ['#dependencies/lib']
|
||||
BASELIB = ['m', 'pthread', 'gomp', 'Half']
|
||||
BASELIB = ['m', 'pthread', 'Half']
|
||||
OEXRINCLUDE = ['#dependencies/include/OpenEXR']
|
||||
OEXRLIB = ['IlmImf', 'Imath', 'Iex', 'z']
|
||||
PNGLIB = ['png']
|
||||
|
|
|
@ -125,13 +125,15 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\src\samplers\sobolseq.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\veramono14_dsc.h">
|
||||
<ClInclude Include="..\src\libhw\data\veramono14_dsc.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\vera14_dsc.h">
|
||||
<ClInclude Include="..\src\libhw\data\vera14_dsc.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\veramono14_png.h">
|
||||
<ClInclude Include="..\src\libhw\data\shaders.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\vera14_png.h">
|
||||
<ClInclude Include="..\src\libhw\data\veramono14_png.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\data\vera14_png.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\medium\materials.h">
|
||||
</ClInclude>
|
||||
|
@ -203,6 +205,8 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\src\films\banner.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\films\annotations.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\shapes\shapegroup.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\shapes\hair.h">
|
||||
|
@ -287,14 +291,14 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\volume.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\sahkdtree4.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\integrator.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\subsurface.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\texture.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\track.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\triaccel_sse.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\bsdf.h">
|
||||
|
@ -385,6 +389,8 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\matrix.inl">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\math.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\ssemath.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\normal.h">
|
||||
|
@ -409,6 +415,8 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\statistics.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\spline.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\thread.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\aabb_sse.h">
|
||||
|
@ -431,6 +439,8 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\brent.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\track.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\chisquare.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\sched_remote.h">
|
||||
|
@ -455,8 +465,6 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\class.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\stl.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\warp.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\util.h">
|
||||
|
@ -511,6 +519,8 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\gpugeometry.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\shadow.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\glrenderer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\glxdevice.h">
|
||||
|
@ -629,8 +639,6 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\photonmap.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\track.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\renderjob.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\intersection.cpp">
|
||||
|
@ -757,6 +765,8 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\libhw\vpl.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libhw\shadow.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libhw\basicshader.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mitsuba\mitsuba.cpp">
|
||||
|
@ -805,6 +815,10 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\logger.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\spline.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\track.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\formatter.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\bitmap.cpp">
|
||||
|
@ -937,6 +951,8 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\main.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\test_simdtonemap.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\programsettingsdlg.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\symlinks_auth.cpp">
|
||||
|
@ -1001,12 +1017,8 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\addimages.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\ttest.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\kdbench.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\uflakefit.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\joinrgb.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\cylclip.cpp">
|
||||
|
@ -1021,6 +1033,8 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\ply\ply_parser.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\cube.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\serialized.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\obj.cpp">
|
||||
|
@ -1033,9 +1047,9 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\hair.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\ply.cpp">
|
||||
<ClCompile Include="..\src\shapes\deformable.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\animatedinstance.cpp">
|
||||
<ClCompile Include="..\src\shapes\ply.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\cylinder.cpp">
|
||||
</ClCompile>
|
||||
|
|
|
@ -9,136 +9,136 @@
|
|||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\converter">
|
||||
<UniqueIdentifier>{b54fb131-7e86-4e08-bba2-828939a038ff}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{81dd9e3e-7bca-44a1-a313-76fb5af5ab0c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\bsdfs">
|
||||
<UniqueIdentifier>{62e70ba9-1509-4ecb-9c06-8de3ef48cd47}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7112f301-f6d5-4351-ae06-4a29910a3766}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\librender">
|
||||
<UniqueIdentifier>{81da027f-f282-46cb-a88d-abc84969dbf8}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{15522c16-64b9-487e-b9fe-dea0094cb5c1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\samplers">
|
||||
<UniqueIdentifier>{8364b08a-50e5-471b-bfaa-4e45915df101}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4df10a81-6f13-45ae-9a39-ce009db3a659}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\sensors">
|
||||
<UniqueIdentifier>{bb52270c-4a49-423b-ad02-4a7c042295c2}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0c722d61-5189-477d-b242-2fa2ad26c83c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libhw">
|
||||
<UniqueIdentifier>{c4330c75-0353-41ab-a809-1471f359aec6}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{d849b48a-b61d-4540-81ab-f5228fd6fa93}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libhw\data">
|
||||
<UniqueIdentifier>{32a38ee8-b255-4e23-8efc-9491fc27c645}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\mitsuba">
|
||||
<UniqueIdentifier>{0f1ec875-44fb-46b2-9116-26d659410d97}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{9f6ef52b-2504-4722-a200-7aaa9603088a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libcore">
|
||||
<UniqueIdentifier>{ab910bc2-a0a5-4f02-8232-396937071149}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{6c49af9f-8cac-477f-825b-ccb368e313c6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\tests">
|
||||
<UniqueIdentifier>{dff3f942-f016-4bad-aa2c-63c444401a94}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{182aef81-5fdf-4eb1-a7d3-5b1d7d5de2b5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\medium">
|
||||
<UniqueIdentifier>{855b0594-d28c-486a-b081-72991219654e}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{81241aff-695b-4556-bf46-e9d3ac4aa7fb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\emitters">
|
||||
<UniqueIdentifier>{08449c4a-89f1-4b5b-a756-2bd2f03bf566}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\emitters\sky">
|
||||
<UniqueIdentifier>{8437086b-afc9-48b6-a358-53d4df044974}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{f4218b48-d878-435b-915a-8da9727666b1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\emitters\sunsky">
|
||||
<UniqueIdentifier>{d9802d62-8614-401a-afa6-941271c63386}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{e6e1a06f-b795-4a12-9b0c-0c730e0b2ac6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\subsurface">
|
||||
<UniqueIdentifier>{65e0e20a-2809-4352-8c81-69a0a3824fa9}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{231a82e9-6b4b-4a95-995c-8abd0b6149b3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\rfilters">
|
||||
<UniqueIdentifier>{8ea19f58-a2c0-4a30-bc79-817da2f1a1ed}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4c70e19a-a935-4b0f-88e3-10683b03f66c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\volume">
|
||||
<UniqueIdentifier>{753c9d80-ceb0-4932-8097-5c7cac92e091}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4a433329-84ca-4a8b-938e-4d06c21ec6ff}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\mtsgui">
|
||||
<UniqueIdentifier>{b4290489-566b-4576-847b-392b4c45f1f1}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4414bb60-269f-4934-9dc9-58bbed35bc1d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\mtsgui\pch">
|
||||
<UniqueIdentifier>{ad07dceb-214e-42e1-933d-c8ceeecd1389}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4bc23857-f9a2-453d-bc64-8c9ebc5aff42}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\mtsgui\resources">
|
||||
<UniqueIdentifier>{3ee94c12-30fb-4f65-8781-f7b5e8a95db2}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{a9318f22-caaa-40af-b8fc-9b8051ec0859}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\mtsgui\shaders">
|
||||
<UniqueIdentifier>{813aba46-5b9d-4290-9a31-18e77952929e}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{fba5da81-e3f2-4fbe-98d7-807aaa2c2cf3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\phase">
|
||||
<UniqueIdentifier>{55bcc3cd-7f6b-4bb6-b22e-b731ed0451fb}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{abd6883d-375b-4d85-bb93-12952995332d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\utils">
|
||||
<UniqueIdentifier>{6ebccae2-fbfd-4a3f-9bfc-7e9dbd2b6d74}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4c9fdf84-d6a6-47f8-8d58-c01ed8351fa0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\films">
|
||||
<UniqueIdentifier>{a339ab19-2bed-4d03-afdc-d73223648b72}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{366f9975-2268-4124-81b9-87e7c2c03b1e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\shapes">
|
||||
<UniqueIdentifier>{87b01999-0b73-481b-b8fa-b66f594f65be}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8d2d02ea-1957-4256-8046-f525d13e7ba5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\shapes\ply">
|
||||
<UniqueIdentifier>{5870cf94-fb1b-44c0-90f2-32c3c8cbf6b7}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8438e074-8733-4689-95ba-86145dd9fd9d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators">
|
||||
<UniqueIdentifier>{90263b28-e65b-4d41-92cb-a0d1dac22564}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{9d35d85d-280c-49ef-869a-ffaa0602f9f5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\vpl">
|
||||
<UniqueIdentifier>{453d13c1-1847-4a18-8f2e-028913b4ec43}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{6df94c72-e89d-451e-ad6b-160ea0313077}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\misc">
|
||||
<UniqueIdentifier>{e4baad7e-ee3c-4085-961f-2851c0ed2b8f}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7bec8429-3bb9-4dfd-8008-a10c675a9818}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\direct">
|
||||
<UniqueIdentifier>{a7ab51c2-5596-458f-b5f0-1129dc3dbbf5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{747a1613-4c01-46ef-ba17-92d2286890ad}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\pssmlt">
|
||||
<UniqueIdentifier>{a7456898-2253-48d8-abec-9c86311cca64}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{516a0fc3-a824-4486-b50c-f3165d1d8361}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\photonmapper">
|
||||
<UniqueIdentifier>{cb9f48b8-6f25-4c9d-9d2c-b1a67cc80427}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{bddbc784-474a-4cd3-bbea-3123048dbfaa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\path">
|
||||
<UniqueIdentifier>{b44ee927-e827-4c46-bbce-c7a1b705b63b}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7bba2a7a-8cd3-47bd-9ab2-e33939d4eba6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\mlt">
|
||||
<UniqueIdentifier>{40540c0e-02d6-4296-bbdf-87dfd9f7f213}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{32cdfdd7-c3bb-41f2-b433-10165963f9ed}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\bdpt">
|
||||
<UniqueIdentifier>{430d27a2-66db-4169-bb48-aeb0b65e4d1a}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{49edc93d-4305-45a8-a6d9-ae283837d46a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\erpt">
|
||||
<UniqueIdentifier>{a247e523-dbaf-4fb8-b284-6c8c5cbc09a5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{d24cf1e6-a301-42e8-9fc1-26fe0ddc3f04}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\integrators\ptracer">
|
||||
<UniqueIdentifier>{91d6db52-180b-4dde-9339-807917e42f4e}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{3df649be-39d5-4416-8776-427a1696c016}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\textures">
|
||||
<UniqueIdentifier>{8ae0e3a3-87db-4e93-bb20-9d198040ae86}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2e68088f-97e2-4dee-91f5-c85e3e36dd74}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libbidir">
|
||||
<UniqueIdentifier>{0049f7d1-4211-4010-b53c-3ee99244046e}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{f7674a86-b0a5-484c-9db3-a20500b9bbf9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\libpython">
|
||||
<UniqueIdentifier>{8bddb89b-fa54-448a-a4b3-294f18d45ded}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{f41987e3-e0b9-431d-b37b-5931db380b09}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\mitsuba">
|
||||
<UniqueIdentifier>{082f589c-eb3f-47a4-b2f6-fbd6d89dec07}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{88ed597b-50ba-4d6f-bf50-ae8f5fa17789}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\mitsuba\render">
|
||||
<UniqueIdentifier>{a7f59027-bc87-4d28-9b90-eb5be186d8a7}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{5499a8e9-ef31-4ab9-a58f-d3a36a784004}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\mitsuba\core">
|
||||
<UniqueIdentifier>{f5410d0f-0a22-4579-afbf-8e13db8fa3d5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{b74f25a9-ff20-4888-8dfc-57dd968b0b8d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\mitsuba\hw">
|
||||
<UniqueIdentifier>{ebe2b998-26de-4e92-8618-c739cb43a5f2}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{18246123-74da-4fee-8581-bd2860451c40}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\mitsuba\bidir">
|
||||
<UniqueIdentifier>{4f4d9d4b-3f44-4d56-9a18-16b94e753706}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{3fdeab5a-5ccf-41c6-bf05-d9f7f510c741}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Source Files">
|
||||
|
@ -247,9 +247,6 @@
|
|||
<ClCompile Include="..\src\librender\photonmap.cpp">
|
||||
<Filter>Source Files\librender</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\track.cpp">
|
||||
<Filter>Source Files\librender</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\librender\renderjob.cpp">
|
||||
<Filter>Source Files\librender</Filter>
|
||||
</ClCompile>
|
||||
|
@ -439,6 +436,9 @@
|
|||
<ClCompile Include="..\src\libhw\vpl.cpp">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libhw\shadow.cpp">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libhw\basicshader.cpp">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
</ClCompile>
|
||||
|
@ -511,6 +511,12 @@
|
|||
<ClCompile Include="..\src\libcore\logger.cpp">
|
||||
<Filter>Source Files\libcore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\spline.cpp">
|
||||
<Filter>Source Files\libcore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\track.cpp">
|
||||
<Filter>Source Files\libcore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\libcore\formatter.cpp">
|
||||
<Filter>Source Files\libcore</Filter>
|
||||
</ClCompile>
|
||||
|
@ -709,6 +715,9 @@
|
|||
<ClCompile Include="..\src\mtsgui\main.cpp">
|
||||
<Filter>Source Files\mtsgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\test_simdtonemap.cpp">
|
||||
<Filter>Source Files\mtsgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\mtsgui\programsettingsdlg.cpp">
|
||||
<Filter>Source Files\mtsgui</Filter>
|
||||
</ClCompile>
|
||||
|
@ -805,15 +814,9 @@
|
|||
<ClCompile Include="..\src\utils\addimages.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\ttest.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\kdbench.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\uflakefit.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils\joinrgb.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
|
@ -835,6 +838,9 @@
|
|||
<ClCompile Include="..\src\shapes\ply\ply_parser.cpp">
|
||||
<Filter>Source Files\shapes\ply</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\cube.cpp">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\serialized.cpp">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClCompile>
|
||||
|
@ -853,10 +859,10 @@
|
|||
<ClCompile Include="..\src\shapes\hair.cpp">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\ply.cpp">
|
||||
<ClCompile Include="..\src\shapes\deformable.cpp">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\animatedinstance.cpp">
|
||||
<ClCompile Include="..\src\shapes\ply.cpp">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\shapes\cylinder.cpp">
|
||||
|
@ -1035,17 +1041,20 @@
|
|||
<ClInclude Include="..\src\samplers\sobolseq.h">
|
||||
<Filter>Source Files\samplers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\veramono14_dsc.h">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
<ClInclude Include="..\src\libhw\data\veramono14_dsc.h">
|
||||
<Filter>Source Files\libhw\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\vera14_dsc.h">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
<ClInclude Include="..\src\libhw\data\vera14_dsc.h">
|
||||
<Filter>Source Files\libhw\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\veramono14_png.h">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
<ClInclude Include="..\src\libhw\data\shaders.h">
|
||||
<Filter>Source Files\libhw\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\vera14_png.h">
|
||||
<Filter>Source Files\libhw</Filter>
|
||||
<ClInclude Include="..\src\libhw\data\veramono14_png.h">
|
||||
<Filter>Source Files\libhw\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\libhw\data\vera14_png.h">
|
||||
<Filter>Source Files\libhw\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\medium\materials.h">
|
||||
<Filter>Source Files\medium</Filter>
|
||||
|
@ -1152,6 +1161,9 @@
|
|||
<ClInclude Include="..\src\films\banner.h">
|
||||
<Filter>Source Files\films</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\films\annotations.h">
|
||||
<Filter>Source Files\films</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\shapes\shapegroup.h">
|
||||
<Filter>Source Files\shapes</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1278,6 +1290,9 @@
|
|||
<ClInclude Include="..\include\mitsuba\render\volume.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\sahkdtree4.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\integrator.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1287,9 +1302,6 @@
|
|||
<ClInclude Include="..\include\mitsuba\render\texture.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\track.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\render\triaccel_sse.h">
|
||||
<Filter>Header Files\mitsuba\render</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1425,6 +1437,9 @@
|
|||
<ClInclude Include="..\include\mitsuba\core\matrix.inl">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\math.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\ssemath.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1461,6 +1476,9 @@
|
|||
<ClInclude Include="..\include\mitsuba\core\statistics.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\spline.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\thread.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1494,6 +1512,9 @@
|
|||
<ClInclude Include="..\include\mitsuba\core\brent.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\track.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\chisquare.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1530,9 +1551,6 @@
|
|||
<ClInclude Include="..\include\mitsuba\core\class.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\stl.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\core\warp.h">
|
||||
<Filter>Header Files\mitsuba\core</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1614,6 +1632,9 @@
|
|||
<ClInclude Include="..\include\mitsuba\hw\gpugeometry.h">
|
||||
<Filter>Header Files\mitsuba\hw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\shadow.h">
|
||||
<Filter>Header Files\mitsuba\hw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\mitsuba\hw\glrenderer.h">
|
||||
<Filter>Header Files\mitsuba\hw</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -6,15 +6,17 @@ if (NOT DEFINED MTS_VERSION)
|
|||
message(FATAL_ERROR "This file has to be included from the main build file.")
|
||||
endif()
|
||||
|
||||
# Image format definitions
|
||||
if (PNG_FOUND)
|
||||
add_definitions(-DMTS_HAS_LIBPNG=1)
|
||||
endif()
|
||||
if (JPEG_FOUND)
|
||||
add_definitions(-DMTS_HAS_LIBJPEG=1)
|
||||
endif()
|
||||
if (OPENEXR_FOUND)
|
||||
add_definitions(-DMTS_HAS_OPENEXR=1)
|
||||
# Default initial compiler flags which may be modified by advanced users
|
||||
if (MTS_CMAKE_INIT)
|
||||
set(MTS_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
set(MTS_CXX_FLAGS "-fvisibility=hidden -pipe -march=nocona -mfpmath=sse -ffast-math -Wall -Winvalid-pch")
|
||||
endif()
|
||||
if (MTS_CXX_FLAGS)
|
||||
set(CMAKE_CXX_FLAGS "${MTS_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" CACHE
|
||||
STRING "Flags used by the compiler during all build types." FORCE)
|
||||
set(MTS_CXX_FLAGS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Top level configuration definitions
|
||||
|
@ -107,15 +109,7 @@ endif()
|
|||
if (WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(-DWIN64)
|
||||
endif()
|
||||
|
||||
|
||||
# Main mitsuba include directory
|
||||
include_directories("include")
|
||||
|
||||
# Includes for the common libraries
|
||||
include_directories(${Boost_INCLUDE_DIRS} ${Eigen_INCLUDE_DIR})
|
||||
|
||||
# If we are using the system OpenEXR, add its headers which half.h requires
|
||||
if (OPENEXR_FOUND)
|
||||
include_directories(${ILMBASE_INCLUDE_DIRS})
|
||||
if (MSVC AND MTS_SSE AND NOT CMAKE_CL_64)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:SSE2")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
|
||||
endif()
|
||||
|
|
|
@ -244,3 +244,23 @@ CMAKE_DEPENDENT_OPTION(BUILD_PYTHON "Build the Python bindings." ON
|
|||
if (PYTHONLIBS_FOUND AND mts_boost_PYTHON_FOUND)
|
||||
set (PYTHON_FOUND TRUE)
|
||||
endif ()
|
||||
|
||||
|
||||
# Includes for the common libraries
|
||||
include_directories(${Boost_INCLUDE_DIRS} ${Eigen_INCLUDE_DIR})
|
||||
|
||||
# If we are using the system OpenEXR, add its headers which half.h requires
|
||||
if (OPENEXR_FOUND)
|
||||
include_directories(${ILMBASE_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Image format definitions
|
||||
if (PNG_FOUND)
|
||||
add_definitions(-DMTS_HAS_LIBPNG=1)
|
||||
endif()
|
||||
if (JPEG_FOUND)
|
||||
add_definitions(-DMTS_HAS_LIBJPEG=1)
|
||||
endif()
|
||||
if (OPENEXR_FOUND)
|
||||
add_definitions(-DMTS_HAS_OPENEXR=1)
|
||||
endif()
|
||||
|
|
|
@ -141,14 +141,16 @@ function(mts_win_resource target_filename name ext description)
|
|||
endif()
|
||||
|
||||
set(RC_DESCRIPTION "${description}")
|
||||
#TODO Add the hg revision number to the version, e.g. 0.0.0-hg000000000000
|
||||
if (MTS_HAS_VALID_REV)
|
||||
set(RC_VERSION "${MTS_VERSION}-${MTS_VERSION_BUILD}hg${MTS_REV_ID}")
|
||||
else()
|
||||
set(RC_VERSION "${MTS_VERSION}")
|
||||
set(RC_VERSION_COMMA "${MTS_VERSION}.0")
|
||||
string(REPLACE "." "," RC_VERSION_COMMA ${RC_VERSION_COMMA})
|
||||
endif()
|
||||
set(RC_VERSION_COMMA "${MTS_VERSION_MAJOR},${MTS_VERSION_MINOR},${MTS_VERSION_PATCH},0")
|
||||
set(RC_FILENAME "${name}${ext}")
|
||||
set(RC_NAME "${name}")
|
||||
#TODO Set the year programmatically
|
||||
set(RC_YEAR "2012")
|
||||
# MTS_DATE has the format YYYY.MM.DD
|
||||
string(SUBSTRING "${MTS_DATE}" 0 4 RC_YEAR)
|
||||
|
||||
configure_file("${RC_FILE}" "${target_filename}" ESCAPE_QUOTES @ONLY)
|
||||
endfunction()
|
||||
|
@ -308,15 +310,15 @@ macro (add_mts_plugin _plugin_name)
|
|||
add_library (${_plugin_name} MODULE ${_plugin_srcs})
|
||||
endif ()
|
||||
|
||||
set(core_libraries "mitsuba-core" "mitsuba-render")
|
||||
set(_plugin_core_libraries "mitsuba-core" "mitsuba-render")
|
||||
if (_plugin_MTS_HW)
|
||||
list(APPEND core_libraries "mitsuba-hw")
|
||||
list(APPEND _plugin_core_libraries "mitsuba-hw")
|
||||
endif()
|
||||
if (_plugin_MTS_BIDIR)
|
||||
list(APPEND core_libraries "mitsuba-bidir")
|
||||
list(APPEND _plugin_core_libraries "mitsuba-bidir")
|
||||
endif()
|
||||
target_link_libraries (${_plugin_name}
|
||||
${core_libraries} ${_plugin_LINK_LIBRARIES})
|
||||
${_plugin_core_libraries} ${_plugin_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties (${_plugin_name} PROPERTIES PREFIX "")
|
||||
if (APPLE)
|
||||
|
@ -367,6 +369,7 @@ endif()
|
|||
# [RES_ICON filename]
|
||||
# [RES_DESCRIPTION "Description string"]
|
||||
# [NO_INSTALL]
|
||||
# [MTS_HW] [MTS_BIDIR]
|
||||
# [NO_MTS_PCH | PCH pch_header] )
|
||||
#
|
||||
# The executable name is taken from the first argument. The target gets
|
||||
|
@ -375,6 +378,11 @@ endif()
|
|||
# (for example, libpng) may be specified after the optionl LINK_LIBRARIES
|
||||
# keyword.
|
||||
#
|
||||
# By default the executables are linked against mitsuba-core and mitsuba-render.
|
||||
# When MTS_HW is set, the executable will be linked against with mitsuba-hw.
|
||||
# When MTS_BIDIR is specified, the executable will also be linked against
|
||||
# mitsuba-bidir.
|
||||
#
|
||||
# The optional keyword WIN32, if presents, gets passed to add_executable(...)
|
||||
# to produce a Windows executable using winmain, thus it won't have a
|
||||
# console. The NO_INSTALL keyword causes the target not to be installed.
|
||||
|
@ -388,7 +396,7 @@ endif()
|
|||
# builds; other platforms simply ignore this value as with RES_ICON.
|
||||
#
|
||||
macro (add_mts_exe _exe_name)
|
||||
CMAKE_PARSE_ARGUMENTS(_exe "WIN32;NO_INSTALL;NO_MTS_PCH"
|
||||
CMAKE_PARSE_ARGUMENTS(_exe "WIN32;NO_INSTALL;MTS_HW;MTS_BIDIR;NO_MTS_PCH"
|
||||
"PCH;RES_ICON;RES_DESCRIPTION" "LINK_LIBRARIES" ${ARGN})
|
||||
set (_exe_srcs ${_exe_UNPARSED_ARGUMENTS})
|
||||
if (_exe_WIN32)
|
||||
|
@ -425,8 +433,15 @@ macro (add_mts_exe _exe_name)
|
|||
else ()
|
||||
add_executable (${_exe_name} ${_exe_TYPE} ${_exe_srcs})
|
||||
endif ()
|
||||
target_link_libraries (${_exe_name}
|
||||
${MTS_CORELIBS} ${_exe_LINK_LIBRARIES})
|
||||
|
||||
set(_exe_core_libraries "mitsuba-core" "mitsuba-render")
|
||||
if (_exe_MTS_HW)
|
||||
list(APPEND _exe_core_libraries "mitsuba-hw")
|
||||
endif()
|
||||
if (_exe_MTS_BIDIR)
|
||||
list(APPEND _exe_core_libraries "mitsuba-bidir")
|
||||
endif()
|
||||
target_link_libraries (${_exe_name} ${_exe_core_libraries} ${_exe_LINK_LIBRARIES})
|
||||
if (WIN32)
|
||||
set_target_properties (${_exe_name} PROPERTIES VERSION "${MTS_VERSION}")
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
# ============================================================================
|
||||
# HDRITools - High Dynamic Range Image Tools
|
||||
# Copyright 2008-2011 Program of Computer Graphics, Cornell University
|
||||
#
|
||||
# Distributed under the OSI-approved MIT License (the "License");
|
||||
# see accompanying file LICENSE for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
# ---------------------------------------------------------------------------
|
||||
# Primary author:
|
||||
# Edgar Velazquez-Armendariz <cs#cornell#edu - eva5>
|
||||
# ============================================================================
|
||||
|
||||
# - Sets up the version info variables
|
||||
# This module provides a function intended to be called ONLY from the root dir:
|
||||
# MTS_GET_VERSION_INFO()
|
||||
# This function will read the "include/mitsuba/core/version.h" file and execute
|
||||
# "hg", setting the following variables:
|
||||
# MTS_VERSION - Full version string: <major>.<minor>.<patch>
|
||||
# MTS_VERSION_MAJOR
|
||||
# MTS_VERSION_MINOR
|
||||
# MTS_VERSION_PATCH
|
||||
# MTS_VERSION_BUILD - Simple build number based on MTS_DATE,
|
||||
# encoded as YYYYMMDD
|
||||
# MTS_HAS_VALID_REV - Flag to indicate whether MTS_REV_ID is set
|
||||
# MTS_REV_ID - First 12 digits of the mercurial revision ID
|
||||
# MTS_DATE - Represents the code date as YYYY.MM.DD
|
||||
# MTS_MACLS_VERSION - A version for Mac Launch Services from the version and
|
||||
# code date, in the format nnnnn.nn.nn[hgXXXXXXXXXXXX]
|
||||
|
||||
function(MTS_GET_VERSION_INFO)
|
||||
|
||||
# Simple, internal macro for zero padding values. Assumes that the number of
|
||||
# digits is enough. Note that this method overwrites the variable!
|
||||
macro(ZERO_PAD NUMBER_VAR NUM_DIGITS)
|
||||
set(_val ${${NUMBER_VAR}})
|
||||
set(${NUMBER_VAR} "")
|
||||
foreach(dummy_var RANGE 1 ${NUM_DIGITS})
|
||||
math(EXPR _digit "${_val} % 10")
|
||||
set(${NUMBER_VAR} "${_digit}${${NUMBER_VAR}}")
|
||||
math(EXPR _val "${_val} / 10")
|
||||
endforeach()
|
||||
unset(_val)
|
||||
unset(_digit)
|
||||
endmacro()
|
||||
|
||||
|
||||
# Uses hg to get the version string and the date of such revision
|
||||
# Based on info from:
|
||||
# http://mercurial.selenic.com/wiki/VersioningWithMake (January 2011)
|
||||
|
||||
# Try to directly get the information assuming the source is within a repo
|
||||
find_program(HG_CMD hg DOC "Mercurial command line executable")
|
||||
mark_as_advanced(HG_CMD)
|
||||
if (HG_CMD)
|
||||
execute_process(
|
||||
COMMAND "${HG_CMD}" -R "${PROJECT_SOURCE_DIR}"
|
||||
parents --template "{node|short},{date|shortdate}"
|
||||
OUTPUT_VARIABLE HG_INFO
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if (HG_INFO)
|
||||
# Extract the revision ID and the date
|
||||
string(REGEX REPLACE "(.+),.+" "\\1" MTS_REV_ID "${HG_INFO}")
|
||||
string(REGEX REPLACE ".+,(.+)-(.+)-(.+)" "\\1.\\2.\\3"
|
||||
MTS_DATE "${HG_INFO}")
|
||||
set(MTS_REV_ID ${MTS_REV_ID} PARENT_SCOPE)
|
||||
set(MTS_DATE ${MTS_DATE} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If that failed, try grabbing the id from .hg_archival.txt, in case a tarball
|
||||
# made by "hg archive" is being used
|
||||
if (NOT MTS_REV_ID)
|
||||
set(HG_ARCHIVAL_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/.hg_archival.txt")
|
||||
# Try to read from the file generated by "hg archive"
|
||||
if (EXISTS "${HG_ARCHIVAL_FILENAME}")
|
||||
file(READ "${HG_ARCHIVAL_FILENAME}" HG_ARCHIVAL_TXT)
|
||||
# Extract just the first 12 characters of the node
|
||||
string(REGEX REPLACE ".*node:[ \\t]+(............).*" "\\1"
|
||||
MTS_REV_ID "${HG_ARCHIVAL_TXT}")
|
||||
set(MTS_REV_ID ${MTS_REV_ID} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT MTS_DATE)
|
||||
# The Windows "date" command output depends on the regional settings
|
||||
if (WIN32)
|
||||
set(GETDATE_CMD "${PROJECT_SOURCE_DIR}/data/windows/getdate.exe")
|
||||
set(GETDATE_ARGS "")
|
||||
else()
|
||||
set(GETDATE_CMD "date")
|
||||
set(GETDATE_ARGS "+'%Y.%m.%d'")
|
||||
endif()
|
||||
execute_process(COMMAND "${GETDATE_CMD}" ${GETDATE_ARGS}
|
||||
OUTPUT_VARIABLE MTS_DATE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if (NOT MTS_DATE)
|
||||
message(FATAL_ERROR "Unable to get a build date!")
|
||||
endif()
|
||||
set(MTS_DATE ${MTS_DATE} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if (MTS_REV_ID)
|
||||
set (MTS_HAS_VALID_REV 1)
|
||||
else()
|
||||
message(WARNING "Unable to find the mercurial revision id.")
|
||||
set (MTS_HAS_VALID_REV 0)
|
||||
endif()
|
||||
set(MTS_HAS_VALID_REV ${MTS_HAS_VALID_REV} PARENT_SCOPE)
|
||||
|
||||
|
||||
# Read version (MTS_VERSION) from include/mitsuba/core/version.h
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/mitsuba/core/version.h" MITSUBA_H REGEX "^#define MTS_VERSION \"[^\"]*\"$")
|
||||
if (MITSUBA_H MATCHES "^.*MTS_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*$")
|
||||
set(MTS_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(MTS_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(MTS_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
set(MTS_VERSION "${MTS_VERSION_MAJOR}.${MTS_VERSION_MINOR}.${MTS_VERSION_PATCH}" PARENT_SCOPE)
|
||||
set(MTS_VERSION_MAJOR ${MTS_VERSION_MAJOR} PARENT_SCOPE)
|
||||
set(MTS_VERSION_MINOR ${MTS_VERSION_MINOR} PARENT_SCOPE)
|
||||
set(MTS_VERSION_PATCH ${MTS_VERSION_PATCH} PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "The mitsuba version could not be determined!")
|
||||
endif()
|
||||
|
||||
# Make a super simple build number from the date
|
||||
if (MTS_DATE MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
||||
set(MTS_VERSION_BUILD
|
||||
"${CMAKE_MATCH_1}${CMAKE_MATCH_2}${CMAKE_MATCH_3}" PARENT_SCOPE)
|
||||
|
||||
# Now make a Mac Launch Services version number based on version and date.
|
||||
# Based on specs from:
|
||||
# http://lists.apple.com/archives/carbon-dev/2006/Jun/msg00139.html (Feb 2011)
|
||||
if (MTS_VERSION_MAJOR GREATER 30 OR
|
||||
MTS_VERSION_MINOR GREATER 14 OR
|
||||
MTS_VERSION_PATCH GREATER 14 OR
|
||||
${CMAKE_MATCH_1} GREATER 2032)
|
||||
message(AUTHOR_WARNING "Mitsuba version violates the Mac LS assumptions")
|
||||
endif()
|
||||
math(EXPR _MACLS_MAJOR "(${MTS_VERSION_MAJOR}+1)*256 + (${MTS_VERSION_MINOR}+1)*16 + ${MTS_VERSION_PATCH}+1")
|
||||
math(EXPR _MACLS_MINOR "((${CMAKE_MATCH_1}-2008)*4) + ((${CMAKE_MATCH_2}-1)*32 + ${CMAKE_MATCH_3})/100")
|
||||
math(EXPR _MACLS_BUILD "((${CMAKE_MATCH_2}-1)*32 + ${CMAKE_MATCH_3})%100")
|
||||
ZERO_PAD(_MACLS_MAJOR 4)
|
||||
ZERO_PAD(_MACLS_MINOR 2)
|
||||
ZERO_PAD(_MACLS_BUILD 2)
|
||||
set(MTS_MACLS_VERSION "${_MACLS_MAJOR}.${_MACLS_MINOR}.${_MACLS_BUILD}")
|
||||
if(MTS_HAS_VALID_REV)
|
||||
set(MTS_MACLS_VERSION "${MTS_MACLS_VERSION}hg${MTS_REV_ID}")
|
||||
endif()
|
||||
set(MTS_MACLS_VERSION ${MTS_MACLS_VERSION} PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Mitsuba date has an unexpected format: ${MTS_DATE}")
|
||||
endif()
|
||||
|
||||
endfunction()
|
|
@ -90,5 +90,7 @@
|
|||
<string>YES</string>
|
||||
<key>BreakpadVendor</key>
|
||||
<string>the Mitsuba authors</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -70,5 +70,7 @@
|
|||
<string>@MTS_VERSION@</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
cp /opt/intel/composer_xe_*/compiler/lib/libiomp5.dylib Mitsuba.app/Contents/Frameworks
|
||||
install_name_tool -id @rpath/libiomp5.dylib Mitsuba.app/Contents/Frameworks/libiomp5.dylib
|
||||
find Mitsuba.app/Contents/MacOS/ Mitsuba.app/plugins -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||
find Mitsuba.app/Contents/Frameworks/libmitsuba-* -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||
find Mitsuba.app/Contents/python -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||
find Mitsuba.app/python -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||
|
|
|
@ -1,3 +1,65 @@
|
|||
mitsuba (0.4.4-1) unstable; urgency=low
|
||||
* Improved Python support for rendering animations and motion blur
|
||||
* Photon mapper logic rewrite to account for certain missing specular paths
|
||||
* Robustness improvements for specular+diffuse materials such as 'plastic'
|
||||
* Fixed a remaining issue in the instancing frame computation code
|
||||
* The thindielectric plugin formerly computed incorrect transmittance values
|
||||
* The cube shape is now centered at the origin by default
|
||||
* The TLS cleanup logic has been fixed to avoid a potential crash in mtssrv
|
||||
* Other minor improvements, which are listed in the repository log
|
||||
-- Wenzel Jakob <wenzel@cs.cornell.edu> Thu, 28 Feb 2013 00:00:00 -0400
|
||||
|
||||
mitsuba (0.4.3-1) unstable; urgency=low
|
||||
* Motion blur: Support for arbitrary linear camera, object, and sensor motion
|
||||
to produce motion blur in renderings.
|
||||
* Render-time annotations: added the ability to tag image files with additional
|
||||
information by means of metadata or text labels.
|
||||
* Hide directly visible emitters: convenient feature for removing an environment
|
||||
light source so that an image can be composited onto documents having a
|
||||
different color.
|
||||
* Improved instancing: more robust instancing code with support for
|
||||
non-rigid transformations.
|
||||
* Threading on Windows: fixed various threading-related issues on Windows that
|
||||
previously caused crashes and deadlocks.
|
||||
* Caching: Caching mechanism to further accelerate the loading of
|
||||
.serialized files.
|
||||
* File dialogs: Native File Open/Save dialogs are now used on Windows.
|
||||
* Python: Improved python bindings; easier usage on MacOS X.
|
||||
* Blender interaction: Fixed a issue where GUI tabs containing scenes created
|
||||
in Blender could not be cloned.
|
||||
* Non-uniform scales: All triangle mesh-based shapes now permit
|
||||
non-uniform scales.
|
||||
* NaNs and friends: Increased resilience against various numerical corner cases.
|
||||
* Index-matched participating media: Fixed an unfortunate regression in volpath
|
||||
regarding index-matched media that was accidentally introduced in 0.4.2.
|
||||
* roughdiffuse: Fixed texturing support in the roughdiffuse plugin.
|
||||
* Photon mapping: Fixed some inaccuracies involving participating media when
|
||||
rendered by the photon mapper and the Beam Radiance Estimate.
|
||||
* Conductors: Switched Fresnel reflectance computations for conductors to the
|
||||
exact expressions predicted by geometric optics (an approximation was
|
||||
previously used).
|
||||
* New cube shape: Added a cube shape plugin for convenience. This does
|
||||
exactly what one would expect.
|
||||
* The rest: As usual, a large number of smaller bugfixes and improvements
|
||||
were below the threshold and are thus not listed individually. The
|
||||
repository log has more details.
|
||||
-- Wenzel Jakob <wenzel@cs.cornell.edu> Tue, 29 Jan 2013 00:00:00 -0400
|
||||
|
||||
mitsuba (0.4.2-1) unstable; urgency=low
|
||||
* Volumetric path tracers: improved sampling when dealing with index-matched medium transitions. This is essentially a re-implementation of an optimization that Mitsuba 0.3.1 already had, but which got lost in the bidirectional rewrite.
|
||||
* Batch tonemapper: due to an unfortunate bug, the batch tonemapper in the last release produced invalid results for images containing an alpha channel. This is now fixed.
|
||||
* Shapes: corrected some differential geometry issues in the "cylinder" and "rectangle" shapes.
|
||||
* MLT: fixed 2-stage MLT, which was producing incorrect results.
|
||||
* MEPT: fixed the handling of directional light sources.
|
||||
* Robustness: got rid of various corner-cases that could produce NaNs.
|
||||
* Filenames: to facilitate loading scenes created on Windows/OSX, the Linux version now resolves files case-insensitively if they could not be found after a case-sensitive search.
|
||||
* Python: added Python bindings for shapes and triangle meshes. The Python plugin should now be easier to load (previously, this was unfortunately rather difficult on several platforms). The documentation was also given an overhaul.
|
||||
* Particle tracing: I've decided to disable the adjoint BSDF for shading normals in the particle tracer, since it causes an unacceptable amount of variance in scenes containing poorly tesselated geometry. This affects the plugins ptracer, ppm, sppm and photonmapper.
|
||||
* Subsurface scattering: fixed parallel network renderings involving the dipole model.
|
||||
* Homogeneous medium & dipole: added many more material presets by Narasimhan et al.
|
||||
* OBJ loader: further robustness improvements to the OBJ loader and the associated MTL material translator.
|
||||
-- Wenzel Jakob <wenzel@cs.cornell.edu> Wed, 31 Oct 2012 00:00:00 -0400
|
||||
|
||||
mitsuba (0.4.1-1) unstable; urgency=low
|
||||
* negative pixel values in textures and environment maps are handled more gracefully.
|
||||
* minor robustness improvements to the OBJ and COLLADA importers.
|
||||
|
|
|
@ -4,10 +4,10 @@ Priority: optional
|
|||
Maintainer: Wenzel Jakob <wenzel@cs.cornell.edu>
|
||||
Build-Depends: debhelper (>= 7), build-essential, scons, qt4-dev-tools,
|
||||
libpng12-dev, libjpeg-dev, libilmbase-dev, libopenexr-dev,
|
||||
libxerces-c-dev, libboost-dev, libglewmx1.5-dev, libxxf86vm-dev,
|
||||
libxerces-c-dev, libboost-dev, libglewmx-dev, libxxf86vm-dev,
|
||||
collada-dom-dev, libboost-system-dev, libboost-filesystem-dev,
|
||||
libboost-python-dev, libboost-thread-dev, libgl1-mesa-dev,
|
||||
libglu1-mesa-dev, pkg-config, libeigen3-dev
|
||||
libglu1-mesa-dev, pkg-config, libeigen3-dev, libxml2-dev
|
||||
Standards-Version: 3.8.3
|
||||
Homepage: http://www.mitsuba-renderer.org
|
||||
|
||||
|
@ -24,7 +24,7 @@ Description: Mitsuba renderer
|
|||
Package: mitsuba-dev
|
||||
Architecture: any
|
||||
Depends: qt4-dev-tools, libpng12-dev, libjpeg-dev, libilmbase-dev,
|
||||
libopenexr-dev, libxerces-c-dev, libboost-dev, libglewmx1.5-dev,
|
||||
libopenexr-dev, libxerces-c-dev, libboost-dev, libglewmx-dev,
|
||||
libxxf86vm-dev, collada-dom-dev, libboost-system-dev,
|
||||
libboost-filesystem-dev, libboost-python-dev, libboost-thread-dev,
|
||||
libeigen3-dev, mitsuba
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Name: mitsuba
|
||||
Version: 0.4.1
|
||||
Version: 0.4.4
|
||||
Release: 1%{?dist}
|
||||
Summary: Mitsuba renderer
|
||||
Group: Applications/Graphics
|
||||
|
@ -35,13 +35,14 @@ mkdir -p $RPM_BUILD_ROOT/usr/share/mitsuba/plugins
|
|||
mkdir -p $RPM_BUILD_ROOT/usr/share/pixmaps
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/applications
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/include
|
||||
strip dist/lib* dist/mtsgui dist/mitsuba dist/mtssrv dist/mtsutil
|
||||
strip dist/lib* dist/mtsgui dist/mitsuba dist/mtssrv dist/mtsutil dist/mtsimport
|
||||
strip dist/plugins/* dist/python/*/*
|
||||
cp dist/libmitsuba-*.so $RPM_BUILD_ROOT%{_libdir}
|
||||
cp dist/mtsgui $RPM_BUILD_ROOT%{_bindir}
|
||||
cp dist/mitsuba $RPM_BUILD_ROOT%{_bindir}
|
||||
cp dist/mtssrv $RPM_BUILD_ROOT%{_bindir}
|
||||
cp dist/mtsutil $RPM_BUILD_ROOT%{_bindir}
|
||||
cp dist/mtsimport $RPM_BUILD_ROOT%{_bindir}
|
||||
cp dist/python/2.7/mitsuba.so $RPM_BUILD_ROOT%{_libdir}/python2.7/lib-dynload
|
||||
cp dist/plugins/* $RPM_BUILD_ROOT/usr/share/mitsuba/plugins
|
||||
cp -Rdp dist/data $RPM_BUILD_ROOT/usr/share/mitsuba/data
|
||||
|
@ -62,6 +63,15 @@ rm -rf $RPM_BUILD_ROOT
|
|||
/usr/include/*
|
||||
%changelog
|
||||
|
||||
* Thu Feb 28 2013 Wenzel Jakob <wenzel@cs.cornell.edu> 0.4.4%{?dist}
|
||||
- Upgrade to version 0.4.4
|
||||
|
||||
* Tue Jan 29 2013 Wenzel Jakob <wenzel@cs.cornell.edu> 0.4.3%{?dist}
|
||||
- Upgrade to version 0.4.3
|
||||
|
||||
* Wed Oct 31 2012 Wenzel Jakob <wenzel@cs.cornell.edu> 0.4.2%{?dist}
|
||||
- Upgrade to version 0.4.2
|
||||
|
||||
* Wed Oct 10 2012 Wenzel Jakob <wenzel@cs.cornell.edu> 0.4.1%{?dist}
|
||||
- Upgrade to version 0.4.1
|
||||
|
||||
|
|
|
@ -10,5 +10,5 @@ Exec=mtsgui %U
|
|||
TryExec=mtsgui
|
||||
Terminal=false
|
||||
StartupNotify=true
|
||||
MimeType=application/xml
|
||||
Icon=mitsuba48.png
|
||||
MimeType=application/xml;image/x-exr;image/x-hdr;
|
||||
Icon=mitsuba48
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include <mitsuba/core/constants.h>
|
||||
#include <mitsuba/core/fwd.h>
|
||||
#include <mitsuba/render/fwd.h>
|
||||
#include <mitsuba/core/stl.h>
|
||||
#include <mitsuba/core/object.h>
|
||||
#include <mitsuba/core/ref.h>
|
||||
#include <mitsuba/core/tls.h>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<xsd:element name="vector" type="point"/>
|
||||
<xsd:element name="boolean" type="boolean"/>
|
||||
<xsd:element name="transform" type="transform"/>
|
||||
<xsd:element name="animation" type="animation"/>
|
||||
<xsd:element name="string" type="string"/>
|
||||
<xsd:element name="spectrum" type="spectrum"/>
|
||||
<xsd:element name="rgb" type="rgb"/>
|
||||
|
@ -314,6 +315,23 @@
|
|||
</xsd:choice>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="animationTransform">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="translate" type="translate"/>
|
||||
<xsd:element name="rotate" type="rotate"/>
|
||||
<xsd:element name="lookAt" type="lookAt"/>
|
||||
<xsd:element name="lookat" type="lookAt"/>
|
||||
<xsd:element name="scale" type="scale"/>
|
||||
<xsd:element name="matrix" type="matrix"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="time" type="doubleType" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="animation">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="transform" type="animationTransform"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="translate">
|
||||
<xsd:attribute name="x" type="doubleType"/>
|
||||
<xsd:attribute name="y" type="doubleType"/>
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*============================================================================
|
||||
HDRITools - High Dynamic Range Image Tools
|
||||
Copyright 2008-2011 Program of Computer Graphics, Cornell University
|
||||
|
||||
Distributed under the OSI-approved MIT License (the "License");
|
||||
see accompanying file LICENSE for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
-----------------------------------------------------------------------------
|
||||
Primary author:
|
||||
Edgar Velazquez-Armendariz <cs#cornell#edu - eva5>
|
||||
============================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
time_t ltime;
|
||||
struct tm *today;
|
||||
FILE *of;
|
||||
#if _MSC_VER >= 1400
|
||||
struct tm timebuf;
|
||||
#endif
|
||||
|
||||
if (argc != 2) {
|
||||
of = stdout;
|
||||
} else {
|
||||
#if _MSC_VER >= 1400
|
||||
if (fopen_s(&of, argv[1], "w") != 0) return 3;
|
||||
#else
|
||||
of = fopen(argv[1], "w");
|
||||
if (!of) return 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
time(<ime);
|
||||
#if _MSC_VER >= 1400
|
||||
if (localtime_s(&timebuf, <ime) != 0) return 1;
|
||||
today = &timebuf;
|
||||
#else
|
||||
today = localtime(<ime);
|
||||
if (!today) return 1;
|
||||
#endif
|
||||
|
||||
fprintf(of, "%d.%02d.%02d", (today->tm_year + 1900),
|
||||
(today->tm_mon + 1), today->tm_mday);
|
||||
if (of != stdout) fclose(of);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2012 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License Version 3
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Mitsuba is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mitsuba/core/platform.h>
|
||||
#if defined(__WINDOWS__)
|
||||
|
||||
// Stub for generating UTF-8 command line arguments from wmain (UTF-16)
|
||||
#include <Windows.h>
|
||||
|
||||
extern int mts_main(int argc, char **argv);
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ArgsUTF8 {
|
||||
public:
|
||||
ArgsUTF8(int argc, wchar_t *wargv[]) :
|
||||
m_argc(-1), m_argv(NULL), m_data(NULL)
|
||||
{
|
||||
if (argc > 0)
|
||||
m_argc = argc;
|
||||
else
|
||||
return;
|
||||
|
||||
m_argv = new char*[argc];
|
||||
int total = 0;
|
||||
|
||||
// Pass 1: get the lengths of each converted string an allocate data
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
const int lenUtf8 = WideCharToMultiByte(CP_UTF8, 0,
|
||||
wargv[i], -1, NULL, 0, NULL, NULL);
|
||||
if (lenUtf8 != 0) {
|
||||
total += lenUtf8;
|
||||
m_argv[i] = reinterpret_cast<char*>(lenUtf8);
|
||||
} else {
|
||||
m_argc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_argc < 1)
|
||||
return;
|
||||
|
||||
m_data = new char[total];
|
||||
int currOffset = 0;
|
||||
|
||||
// Pass 2: perform the conversion
|
||||
for (int i = 0; i < m_argc; ++i) {
|
||||
int lenUtf8 = reinterpret_cast<int>(m_argv[i]);
|
||||
m_argv[i] = m_data + currOffset;
|
||||
lenUtf8 = WideCharToMultiByte(CP_UTF8, 0,
|
||||
wargv[i], -1, m_argv[i], lenUtf8, NULL, NULL);
|
||||
if (lenUtf8 != 0) {
|
||||
currOffset += lenUtf8;
|
||||
} else {
|
||||
m_argc = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~ArgsUTF8() {
|
||||
if (m_argv != NULL) {
|
||||
delete [] m_argv;
|
||||
}
|
||||
if (m_data != NULL) {
|
||||
delete [] m_data;
|
||||
}
|
||||
}
|
||||
|
||||
inline int argc() const {
|
||||
return m_argc;
|
||||
}
|
||||
|
||||
inline char** argv() const {
|
||||
return m_argv;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_argc;
|
||||
char** m_argv;
|
||||
char* m_data;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// MSDN Documentation:
|
||||
// http://msdn.microsoft.com/en-US/library/fzc2cy7w%28v=vs.110%29.aspx
|
||||
int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) {
|
||||
ArgsUTF8 argsUTF8(argc, wargv);
|
||||
return mts_main(argsUTF8.argc(), argsUTF8.argv());
|
||||
}
|
||||
|
||||
#endif // __WINDOWS__
|
|
@ -1,2 +1,7 @@
|
|||
all:
|
||||
./gendoc.py
|
||||
|
||||
clean:
|
||||
$(RM) main.pdf
|
||||
$(RM) plugins_generated.tex
|
||||
$(RM) *.aux main.bbl main.blg main.log main.out main.toc
|
||||
|
|
|
@ -189,6 +189,13 @@ might start the with parameters such as the following
|
|||
\begin{shell}
|
||||
$\texttt{\$}$ mitsuba -xj 2 -c machine1;machine2;... animation/frame_*.xml
|
||||
\end{shell}
|
||||
Note that this requires a shell capable of expanding the asterisk into a list of
|
||||
filenames. The default Windows shell \code{cmd.exe} does not do this---however,
|
||||
the PowerShell supports the following syntax:
|
||||
\begin{shell}
|
||||
dir frame_*.xml | % $\texttt{\{}$ <path to mitsuba.exe> $\texttt{\$\_}$ $\texttt{\}}$
|
||||
\end{shell}
|
||||
|
||||
\subsection{Direct connection server}
|
||||
\label{sec:mtssrv}
|
||||
A Mitsuba compute node can be created using the \code{mtssrv} executable. By default,
|
||||
|
|
|
@ -129,9 +129,8 @@ scons: $\texttt{done}$ building targets.
|
|||
\end{shell}
|
||||
To run the renderer from the command line, you first have to import it into your shell environment:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
$\text{\$}$ source setpath.sh
|
||||
\end{shell}
|
||||
(note the period at the beginning -- this assumes that you are using \code{bash}).
|
||||
Having set up everything, you can now move on to \secref{basics}.
|
||||
\subsubsection{Creating Debian or Ubuntu Linux packages}
|
||||
The preferred way of redistristributing executables on Debian or Ubuntu Linux is to create
|
||||
|
@ -208,9 +207,8 @@ scons: $\texttt{done}$ building targets.
|
|||
\end{shell}
|
||||
To run the renderer from the command line, you first have to import it into your shell environment:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
$\text{\$}$ source setpath.sh
|
||||
\end{shell}
|
||||
(note the period at the beginning -- this assumes that you are using \code{bash}).
|
||||
Having set up everything, you can now move on to \secref{basics}.
|
||||
\subsubsection{Creating Fedora Core packages}
|
||||
To create \code{RPM} packages, you will need to install the \code{RPM} development tools:
|
||||
|
@ -261,9 +259,9 @@ scons: $\texttt{done}$ building targets.
|
|||
\end{shell}
|
||||
To run the renderer from the command line, you first have to import it into your shell environment:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
$\text{\$}$ source setpath.sh
|
||||
\end{shell}
|
||||
(note the period at the beginning -- this assumes that you are using \code{bash}).
|
||||
|
||||
Having set up everything, you can now move on to \secref{basics}.
|
||||
\subsubsection{Creating Arch Linux packages}
|
||||
Mitsuba ships with a \code{PKGBUILD} file, which automatically builds
|
||||
|
@ -350,7 +348,6 @@ scons: $\texttt{done}$ building targets.
|
|||
\end{shell}
|
||||
To run the renderer from the command line, you first have to import it into your shell environment:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
$\text{\$}$ source setpath.sh
|
||||
\end{shell}
|
||||
(note the period at the beginning -- this assumes that you are using \code{bash}).
|
||||
|
||||
|
|
|
@ -92,12 +92,12 @@ and one or more emitters. Here is a more complex example:
|
|||
<shape type="serialized">
|
||||
<string name="filename" value="lightsource.serialized"/>
|
||||
<transform name="toWorld">
|
||||
<translate x="5" x="-3" z="1"/>
|
||||
<translate x="5" y="-3" z="1"/>
|
||||
</transform>
|
||||
|
||||
<!-- This mesh is an area emitter -->
|
||||
<emitter type="area">
|
||||
<rgb name="intensity" value="100,400,100"/>
|
||||
<rgb name="radiance" value="100,400,100"/>
|
||||
</emitter>
|
||||
</shape>
|
||||
</scene>
|
||||
|
@ -276,7 +276,7 @@ choices are available:
|
|||
\begin{xml}
|
||||
<matrix value="0 -0.53 0 -1.79 0.92 0 0 8.03 0 0 0.53 0 0 0 0 1"/>
|
||||
\end{xml}
|
||||
\item lookat transformations --- this is primarily useful for setting up cameras (and spot lights). The \code{origin} coordinates
|
||||
\item \code{lookat} transformations --- this is primarily useful for setting up cameras (and spot lights). The \code{origin} coordinates
|
||||
specify the camera origin, \code{target} is the point that the camera will look at, and the
|
||||
(optional) \code{up} parameter determines the ``upward'' direction in the final rendered image.
|
||||
The \code{up} parameter is not needed for spot lights.
|
||||
|
@ -286,7 +286,38 @@ The \code{up} parameter is not needed for spot lights.
|
|||
\end{itemize}
|
||||
Cordinates that are zero (for \code{translate} and \code{rotate}) or one (for \code{scale})
|
||||
do not explicitly have to be specified.
|
||||
\subsection{Instancing}
|
||||
\subsection{Animated transformations}
|
||||
Most shapes, emitters, and sensors in Mitsuba can accept both normal transformations
|
||||
and \emph{animated transformations} as parameters. The latter is useful to
|
||||
render scenes involving motion blur (Figure~\ref{fig:animated-transform}). The syntax used to specify these
|
||||
is slightly different:
|
||||
\begin{xml}
|
||||
<animation name="trafoProperty">
|
||||
<transform time="0">
|
||||
.. chained list of transformations as discussed above ..
|
||||
</transform>
|
||||
|
||||
<transform time="1">
|
||||
.. chained list of transformations as discussed above ..
|
||||
</transform>
|
||||
|
||||
.. additional transformations (optional) ..
|
||||
</animation>
|
||||
\end{xml}
|
||||
\renderings{
|
||||
\fbox{\includegraphics[width=.6\textwidth]{images/animated_transform}}\hfill\,
|
||||
\caption{\label{fig:animated-transform}Beware the dragon: a triangle mesh undergoing linear motion with several keyframes (object courtesy of XYZRGB)}
|
||||
}
|
||||
|
||||
Mitsuba then decomposes each transformation into a scale, translation, and
|
||||
rotation component and interpolates\footnote{Using linear interpolation
|
||||
for the scale and translation component and spherical linear quaternion
|
||||
interpolation for the rotation component.} these for intermediate
|
||||
time values.
|
||||
It is important to specify appropriate shutter open/close times
|
||||
to the sensor so that the motion is visible.
|
||||
\newpage
|
||||
\subsection{References}
|
||||
Quite often, you will find yourself using an object (such as a material) in many places. To avoid having
|
||||
to declare it over and over again, which wastes memory, you can make use of references. Here is an example
|
||||
of how this works:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# This script walks through all plugin files and
|
||||
# extracts documentation that should go into the
|
||||
|
@ -52,11 +52,8 @@ def process(path, target):
|
|||
fileList += [fname]
|
||||
|
||||
fileList = []
|
||||
# Wrap the walk function to make this work in python 2 and 3.
|
||||
if pyVer >= 3:
|
||||
os.walk(path, capture, fileList)
|
||||
else:
|
||||
os.path.walk(path, capture, fileList)
|
||||
for (dirname, subdirs, files) in os.walk(path):
|
||||
capture(fileList, dirname, files)
|
||||
|
||||
ordering = [(findOrderID(fname), fname) for fname in fileList]
|
||||
ordering = sorted(ordering, key = lambda entry: entry[0])
|
||||
|
@ -64,34 +61,40 @@ def process(path, target):
|
|||
for entry in ordering:
|
||||
extract(target, entry[1])
|
||||
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
f = open('plugins_generated.tex', 'w')
|
||||
f.write('\input{section_shapes}\n')
|
||||
process('../src/shapes', f)
|
||||
f.write('\input{section_bsdf}\n')
|
||||
process('../src/bsdfs', f)
|
||||
f.write('\input{section_textures}\n')
|
||||
process('../src/textures', f)
|
||||
f.write('\input{section_subsurface}\n')
|
||||
process('../src/subsurface', f)
|
||||
f.write('\input{section_media}\n')
|
||||
process('../src/medium', f)
|
||||
f.write('\input{section_phase}\n')
|
||||
process('../src/phase', f)
|
||||
f.write('\input{section_volumes}\n')
|
||||
process('../src/volume', f)
|
||||
f.write('\input{section_emitters}\n')
|
||||
process('../src/emitters', f)
|
||||
f.write('\input{section_sensors}\n')
|
||||
process('../src/sensors', f)
|
||||
f.write('\input{section_integrators}\n')
|
||||
process('../src/integrators', f)
|
||||
f.write('\input{section_samplers}\n')
|
||||
process('../src/samplers', f)
|
||||
f.write('\input{section_films}\n')
|
||||
process('../src/films', f)
|
||||
f.write('\input{section_rfilters}\n')
|
||||
f.close()
|
||||
os.system('bibtex main.aux')
|
||||
os.system('pdflatex main.tex')
|
||||
#os.system('pdflatex main.tex | grep -i warning | grep -v "Package \(typearea\|hyperref\)"')
|
||||
def process_src(target, src_subdir, section=None):
|
||||
if section is None:
|
||||
section = "section_" + src_subdir
|
||||
target.write('\input{{{0}}}\n'.format(section))
|
||||
process('../src/{0}'.format(src_subdir), target)
|
||||
|
||||
def texify(texfile):
|
||||
from subprocess import Popen, PIPE, check_call
|
||||
version = Popen(["pdflatex", "-version"], stdout=PIPE).communicate()[0]
|
||||
# Call decode() to convert from bytes to string, required in Python 3
|
||||
if re.match('.*MiKTeX.*', version.decode()):
|
||||
# MiKTeX's "texify" calls latex/bibtex in tandem automatically
|
||||
print("Running texify on {0}...".format(texfile))
|
||||
check_call(['texify', '-pq', texfile])
|
||||
else:
|
||||
check_call(['pdflatex', texfile])
|
||||
check_call(['bibtex', texfile.replace('.tex', '.aux')])
|
||||
check_call(['pdflatex', texfile])
|
||||
check_call(['pdflatex', texfile])
|
||||
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
with open('plugins_generated.tex', 'w') as f:
|
||||
process_src(f, 'shapes')
|
||||
process_src(f, 'bsdfs', 'section_bsdf')
|
||||
process_src(f, 'textures')
|
||||
process_src(f, 'subsurface')
|
||||
process_src(f, 'medium', 'section_media')
|
||||
process_src(f, 'phase')
|
||||
process_src(f, 'volume', 'section_volumes')
|
||||
process_src(f, 'emitters')
|
||||
process_src(f, 'sensors')
|
||||
process_src(f, 'integrators')
|
||||
process_src(f, 'samplers')
|
||||
process_src(f, 'films')
|
||||
process_src(f, 'rfilters')
|
||||
|
||||
texify('main.tex')
|
||||
|
|
After Width: | Height: | Size: 233 KiB |
After Width: | Height: | Size: 201 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 326 KiB |
After Width: | Height: | Size: 187 KiB |
|
@ -13,7 +13,7 @@ using hardware acceleration, which certainly doesn't fit into the sampling-based
|
|||
For that reason, it must be implemented as a generic integrator.
|
||||
|
||||
Generally, if you can package up your code to fit into the
|
||||
\code{SampleIntegrator} interface, you should do it, because you'll get
|
||||
\code{SamplingIntegrator} interface, you should do it, because you'll get
|
||||
parallelization and network rendering essentially for free. This is done
|
||||
by transparently sending instances of your integrator class to all participating cores
|
||||
and assigning small image blocks for each one to work on. Also, sampling-based
|
||||
|
@ -38,12 +38,12 @@ In Mitsuba's \code{src/integrators} directory, create a file named
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
class MyIntegrator : public SampleIntegrator {
|
||||
class MyIntegrator : public SamplingIntegrator {
|
||||
public:
|
||||
MTS_DECLARE_CLASS()
|
||||
};
|
||||
|
||||
MTS_IMPLEMENT_CLASS_S(MyIntegrator, false, SampleIntegrator)
|
||||
MTS_IMPLEMENT_CLASS_S(MyIntegrator, false, SamplingIntegrator)
|
||||
MTS_EXPORT_PLUGIN(MyIntegrator, "A contrived integrator");
|
||||
MTS_NAMESPACE_END
|
||||
\end{cpp}
|
||||
|
@ -67,7 +67,7 @@ need to be provided by the implementation --- we'll add those in a moment.
|
|||
|
||||
The three following parameters specify the name of this class (\code{MyIntegrator}),
|
||||
the fact that it is \emph{not} an abstract class (\code{false}), and the name of its
|
||||
parent class (\code{SampleIntegrator}).
|
||||
parent class (\code{SamplingIntegrator}).
|
||||
|
||||
Just below, you can see a line that starts with
|
||||
\code{MTS\_EXPORT\_PLUGIN}. As the name suggests, this line is only necessary
|
||||
|
@ -80,7 +80,7 @@ Let's add an instance variable and a constructor:
|
|||
\begin{cpp}
|
||||
public:
|
||||
/// Initialize the integrator with the specified properties
|
||||
MyIntegrator(const Properties &props) : SampleIntegrator(props) {
|
||||
MyIntegrator(const Properties &props) : SamplingIntegrator(props) {
|
||||
Spectrum defaultColor;
|
||||
defaultColor.fromLinearRGB(0.2f, 0.5f, 0.2f);
|
||||
m_color = props.getSpectrum("color", defaultColor);
|
||||
|
@ -106,13 +106,13 @@ Next, we need to add serialization and unserialization support:
|
|||
\begin{cpp}
|
||||
/// Unserialize from a binary data stream
|
||||
MyIntegrator(Stream *stream, InstanceManager *manager)
|
||||
: SampleIntegrator(stream, manager) {
|
||||
: SamplingIntegrator(stream, manager) {
|
||||
m_color = Spectrum(stream);
|
||||
}
|
||||
|
||||
/// Serialize to a binary data stream
|
||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
SampleIntegrator::serialize(stream, manager);
|
||||
SamplingIntegrator::serialize(stream, manager);
|
||||
m_color.serialize(stream);
|
||||
}
|
||||
\end{cpp}
|
||||
|
@ -168,10 +168,11 @@ radiance along a ray differential: here, we simply return the stored color
|
|||
}
|
||||
\end{cpp}
|
||||
|
||||
Let's try building the plugin: edit the \code{SConstruct} file in the main
|
||||
directory, and add the following line after the comment ''\code{\# Integrators}'':
|
||||
Let's try building the plugin: edit the \code{SConscript} file in the
|
||||
\code{integrator} directory, and add the following line before the
|
||||
last line containing ''\code{Export('plugins')}'':
|
||||
\begin{cpp}
|
||||
plugins += env.SharedLibrary('plugins/myIntegrator', ['src/integrators/myIntegrator.cpp'])
|
||||
plugins += env.SharedLibrary('myIntegrator', ['myIntegrator.cpp'])
|
||||
\end{cpp}
|
||||
After calling, \texttt{scons}, you should be able to use your new integrator
|
||||
in parallel rendering jobs and you'll get something like this:
|
||||
|
@ -205,11 +206,12 @@ we can override the \code{preprocess} function:
|
|||
bool preprocess(const Scene *scene, RenderQueue *queue,
|
||||
const RenderJob *job, int sceneResID, int cameraResID,
|
||||
int samplerResID) {
|
||||
SampleIntegrator::preprocess(scene, queue, job, sceneResID,
|
||||
SamplingIntegrator::preprocess(scene, queue, job, sceneResID,
|
||||
cameraResID, samplerResID);
|
||||
|
||||
const AABB &sceneAABB = scene->getAABB();
|
||||
Point cameraPosition = scene->getCamera()->getPosition();
|
||||
/* Find the camera position at t=0 seconds */
|
||||
Point cameraPosition = scene->getSensor()->getWorldTransform()->eval(0).transformAffine(Point(0.0f));
|
||||
m_maxDist = - std::numeric_limits<Float>::infinity();
|
||||
|
||||
for (int i=0; i<8; ++i)
|
||||
|
@ -276,7 +278,7 @@ into a scene XML file:
|
|||
\end{xml}
|
||||
To support this kind of complex interaction, some information needs to be passed between the
|
||||
integrators, and the \code{RadianceQueryRecord} parameter of the function
|
||||
\code{SampleIntegrator::Li} is used for this.
|
||||
\code{SamplingIntegrator::Li} is used for this.
|
||||
|
||||
This brings us back to the odd way of computing an intersection a moment ago:
|
||||
the reason why we didn't just do this by calling
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
\usepackage{ifthen}
|
||||
\usepackage{longtable}
|
||||
\usepackage{wrapfig}
|
||||
\usepackage{footnote} % savenotes environment
|
||||
|
||||
% Make sure that ligatures remain searchable in the PDF
|
||||
\input glyphtounicode
|
||||
|
@ -39,8 +40,8 @@
|
|||
\setcounter{secnumdepth}{3}
|
||||
\setcounter{tocdepth}{3}
|
||||
|
||||
\newcommand{\MitsubaVersion}{0.4.1}
|
||||
\newcommand{\MitsubaYear}{2012}
|
||||
\newcommand{\MitsubaVersion}{0.4.4}
|
||||
\newcommand{\MitsubaYear}{2013}
|
||||
|
||||
\typearea[current]{last}
|
||||
\raggedbottom
|
||||
|
@ -116,7 +117,7 @@
|
|||
medium,film,sampler,integrator,emitter,sensor,
|
||||
translate,rotate,scale,lookat,point,vector,matrix,
|
||||
include,fscat,volume,alias,rfilter,boolean,
|
||||
subsurface
|
||||
subsurface,animation
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ It is important to keep in mind that other applications may not support this
|
|||
``linearized sRGB'' space---in particular, the Mac OS preview currently
|
||||
does not display images with this encoding correctly.
|
||||
|
||||
\subsubsection{Spectral mode}
|
||||
\subsubsection{Spectral rendering}
|
||||
Some predictive rendering applications will require a more realistic space for
|
||||
interreflection computations. In such cases, Mitsuba can be switched to \emph{spectral mode}.
|
||||
This can be done by compiling it with the \code{SPECTRUM\_SAMPLES=}$n$ parameter
|
||||
|
|
|
@ -49,9 +49,9 @@ MTS_NAMESPACE_END
|
|||
\end{cpp}
|
||||
The file must also be added to the build system: insert the line
|
||||
\begin{shell}
|
||||
plugins += $\texttt{env}$.SharedLibrary('plugins/rot13', ['src/utils/rot13.cpp'])
|
||||
plugins += $\texttt{env}$.SharedLibrary('rot13', ['rot13.cpp'])
|
||||
\end{shell}
|
||||
into the SConscript (near the comment ``\code{Build the plugins -- utilities}''). After compiling
|
||||
into the \code{utils/SConscript} file. After compiling
|
||||
using \code{scons}, the \code{mtsutil} binary should automatically pick up your new utility plugin:
|
||||
\begin{shell}
|
||||
$\texttt{\$}$ mtsutil
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
\section{Python integration}
|
||||
\label{sec:python}
|
||||
A recent feature of Mitsuba is a simple Python interface to the renderer API.
|
||||
A recent feature of Mitsuba is a Python interface to the renderer API.
|
||||
While the interface is still limited at this point, it can already be
|
||||
used for many useful purposes. To access the API, start your Python
|
||||
interpreter and enter
|
||||
\begin{python}
|
||||
import mitsuba
|
||||
\end{python}
|
||||
\paragraph{Mac OS:}
|
||||
For this to work on MacOS X, you will first have to run the ``\emph{Apple
|
||||
Menu}$\to$\emph{Command-line access}'' menu item from within Mitsuba.
|
||||
In the unlikely case that you run into shared library loading issues (this is
|
||||
taken care of by default), you may have to set the \code{LD\_LIBRARY\_PATH}
|
||||
environment variable before starting Python so that it points to where the
|
||||
Mitsuba libraries are installed (e.g. the \code{Mitsuba.app/Contents/Frameworks}
|
||||
directory).
|
||||
|
||||
When Python crashes directly after the \code{import mitsuba} statement,
|
||||
make sure that Mitsuba is linked against the right Python distribution
|
||||
(i.e. matching the \code{python} binary you are using). For e.g. Python
|
||||
2.7, can be done by adjusting the \code{PYTHON27INCLUDE} and
|
||||
\code{PYTHON27LIBDIR} variables in \code{config.py}. For other versions,
|
||||
adjust the numbers accordingly.
|
||||
|
||||
\paragraph{Windows and Linux:}
|
||||
On Windows and \emph{non-packaged} Linux builds, you may have to explicitly
|
||||
specify the required extension search path before issuing the \code{import} command, e.g.:
|
||||
\begin{python}
|
||||
|
@ -29,6 +44,9 @@ os.environ['PATH'] = 'path-to-mitsuba-directory' + os.pathsep + os.environ['PATH
|
|||
|
||||
import mitsuba
|
||||
\end{python}
|
||||
In rare cases when running on Linux, it may also be necessary to set the
|
||||
\code{LD\_LIBRARY\_PATH} environment variable before starting Python so that it
|
||||
points to where the Mitsuba core libraries are installed.
|
||||
|
||||
For an overview of the currently exposed API subset, please refer
|
||||
to the following page: \url{http://www.mitsuba-renderer.org/api/group__libpython.html}.
|
||||
|
@ -64,8 +82,8 @@ classes, function, or entire namespaces when running an interactive Python shell
|
|||
...
|
||||
\end{shell}
|
||||
The docstrings list the currently exported functionality, as well as C++ and Python signatures, but they
|
||||
don't document what these functions actually do. The web API documentation is the preferred source for
|
||||
this information.
|
||||
don't document what these functions actually do. The web API documentation is
|
||||
the preferred source of this information.
|
||||
|
||||
\subsection{Basics}
|
||||
Generally, the Python API tries to mimic the C++ API as closely as possible.
|
||||
|
@ -337,3 +355,43 @@ logger.setLogLevel(EDebug)
|
|||
|
||||
Log(EInfo, 'Test message')
|
||||
\end{python}
|
||||
\subsubsection{Rendering a turntable animation with motion blur}
|
||||
Rendering a turntable animation is a fairly common task that is
|
||||
conveniently accomplished via the Python interface. In a turntable
|
||||
video, the camera rotates around a completely static object or scene.
|
||||
The following snippet does this for the material test ball scene downloadable
|
||||
on the main website, complete with motion blur. It assumes that the
|
||||
scene and scheduler have been set up approriately using one of the previous
|
||||
snippets.
|
||||
\begin{python}
|
||||
sensor = scene.getSensor()
|
||||
sensor.setShutterOpen(0)
|
||||
sensor.setShutterOpenTime(1)
|
||||
|
||||
stepSize = 5
|
||||
for i in range(0,360 / stepSize):
|
||||
rotationCur = Transform.rotate(Vector(0, 0, 1), i*stepSize);
|
||||
rotationNext = Transform.rotate(Vector(0, 0, 1), (i+1)*stepSize);
|
||||
|
||||
trafoCur = Transform.lookAt(rotationCur * Point(0,-6,4),
|
||||
Point(0, 0, .5), rotationCur * Vector(0, 1, 0))
|
||||
trafoNext = Transform.lookAt(rotationNext * Point(0,-6,4),
|
||||
Point(0, 0, .5), rotationNext * Vector(0, 1, 0))
|
||||
|
||||
atrafo = AnimatedTransform()
|
||||
atrafo.appendTransform(0, trafoCur)
|
||||
atrafo.appendTransform(1, trafoNext)
|
||||
atrafo.sortAndSimplify()
|
||||
sensor.setWorldTransform(atrafo)
|
||||
|
||||
scene.setDestinationFile('frame_%03i.png' % i)
|
||||
job = RenderJob('job_%i' % i, scene, queue)
|
||||
job.start()
|
||||
|
||||
queue.waitLeft(0)
|
||||
queue.join()
|
||||
\end{python}
|
||||
A useful property of this approach is that scene loading and initialization
|
||||
must only take place once. Performance-wise, this compares favourably with
|
||||
running many separate rendering jobs, e.g. using the \code{mitsuba}
|
||||
command-line executable.
|
||||
|
|
|
@ -113,3 +113,24 @@ What this means is that they display a rough preview, which improves over time.
|
|||
Leaving them running indefinitely will continually reduce noise (in unbiased algorithms
|
||||
such as Metropolis Light Transport) or noise and bias (in biased
|
||||
rendering techniques such as Progressive Photon Mapping).
|
||||
\newpage
|
||||
\subsubsection*{Hiding directly visible emitters}
|
||||
\label{sec:hideemitters}
|
||||
Several rendering algorithms in Mitsuba have a feature to hide directly
|
||||
visible light sources (e.g. environment maps or area lights). While not
|
||||
particularly realistic, this feature is often convenient to remove a background
|
||||
from a rendering so that it can be pasted into a differently-colored document.
|
||||
|
||||
Note that only directly visible emitters can be hidden using this feature---a
|
||||
reflection on a shiny surface will be unaffected. To perform the kind of
|
||||
compositing shown in Figure~\ref{fig:hideemitters}, it is also necessary to
|
||||
enable the alpha channel in the scene's film instance (Section~\ref{sec:films}).
|
||||
|
||||
\renderings{
|
||||
\unframedrendering{Daylit smoke rendered with \code{hideEmitters} set to \code{false}
|
||||
(the default setting)}{integrator_volpath_normal}
|
||||
\unframedrendering{Rendered with \code{hideEmitters} set to \code{true} and alpha-composited
|
||||
onto a white background.}{integrator_volpath_hideemitters}
|
||||
\caption{\label{fig:hideemitters}An example application of the \code{hideEmitters} parameter
|
||||
together with alpha blending}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,18 @@
|
|||
\subsection{Subsurface scattering models}
|
||||
\label{sec:subsurface}
|
||||
There are two ways of simulating subsurface scattering within Mitsuba:
|
||||
participating media and subsurface scattering models. The latter are described
|
||||
in this section and can be thought of as a first-order approximation of the
|
||||
former. For this reason, subsurface scattering models should be preferred when
|
||||
visually appealing output should be generated quickly and the demands on
|
||||
physical realism are secondary.
|
||||
participating media and subsurface scattering models.
|
||||
|
||||
\begin{description}
|
||||
\item[Subsurface scattering models:] Described in this section. These can be thought
|
||||
of as a first-order approximation of what happens inside a participating medium.
|
||||
They are preferable when visually appealing output should be generated
|
||||
\emph{quickly} and the demands on accuracy are secondary.
|
||||
At the moment, there is only one subsurface scattering model (the
|
||||
\pluginref{dipole}), which is described on the next page.
|
||||
\item[Participating media:] Described in Section~\ref{sec:media}. When modeling
|
||||
subsurface scattering using a participating medium, Mitsuba performs a \emph{full}
|
||||
radiative transport simulation, which correctly accounts for all scattering events.
|
||||
This is more accurate but generally significantly slower.
|
||||
\end{description}
|
||||
|
||||
At the moment, there is only one subsurface scattering model (the
|
||||
\pluginref{dipole}), which is described on the next page.
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief Bidirectional mutatation strategy
|
||||
* \brief Bidirectional mutation strategy
|
||||
*
|
||||
* This class implements a slightly extended version of the bidirectional
|
||||
* mutation proposed by Veach. The main change is that it builds on top of
|
||||
|
|
|
@ -165,7 +165,8 @@ public:
|
|||
* \return The average luminance over the image plane
|
||||
*/
|
||||
Float generateSeeds(size_t sampleCount, size_t seedCount,
|
||||
bool fineGrained, std::vector<PathSeed> &seeds);
|
||||
bool fineGrained, const Bitmap *importanceMap,
|
||||
std::vector<PathSeed> &seeds);
|
||||
|
||||
/**
|
||||
* \brief Compute the average luminance over the image plane
|
||||
|
@ -181,7 +182,8 @@ public:
|
|||
* the random number stream of the underlying \ref ReplayableSampler
|
||||
* to the indicated position and recreates the associated path.
|
||||
*/
|
||||
void reconstructPath(const PathSeed &seed, Path &result);
|
||||
void reconstructPath(const PathSeed &seed,
|
||||
const Bitmap *importanceMap, Path &result);
|
||||
|
||||
/// Return the underlying memory pool
|
||||
inline MemoryPool &getMemoryPool() { return m_pool; }
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
* underlying random number generator has been used
|
||||
* outside of this class
|
||||
*/
|
||||
inline void updateSampleIndex(uint64_t index) { m_sampleIndex = index; }
|
||||
inline void updateSampleIndex(size_t index) { m_sampleIndex = index; }
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
|
|
|
@ -129,6 +129,32 @@ template <typename T> struct TAABB {
|
|||
return (max + min) * (Scalar) 0.5;
|
||||
}
|
||||
|
||||
/// Return the position of one of the corners (in <tt>0..2^dim-1</tt>)
|
||||
inline PointType getCorner(int index) const {
|
||||
PointType result;
|
||||
for (int d=0; d<PointType::dim; ++d) {
|
||||
if (index & (1 << d))
|
||||
result[d] = max[d];
|
||||
else
|
||||
result[d] = min[d];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return a child bounding box in a interval-, quad-, octtree, etc.
|
||||
inline TAABB getChild(int index) const {
|
||||
TAABB result(getCenter());
|
||||
|
||||
for (int d=0; d<PointType::dim; ++d) {
|
||||
if (index & (1 << d))
|
||||
result.max[d] = max[d];
|
||||
else
|
||||
result.min[d] = min[d];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Check whether a point lies on or inside the bounding box
|
||||
inline bool contains(const PointType &vec) const {
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
|
@ -289,19 +315,17 @@ template <typename T> struct TAABB {
|
|||
Float t1 = (minVal - origin) * ray.dRcp[i];
|
||||
Float t2 = (maxVal - origin) * ray.dRcp[i];
|
||||
|
||||
if (t1 > t2) {
|
||||
Float tmp = t1;
|
||||
t1 = t2;
|
||||
t2 = tmp;
|
||||
}
|
||||
if (t1 > t2)
|
||||
std::swap(t1, t2);
|
||||
|
||||
nearT = std::max(nearT, t1);
|
||||
farT = std::min(farT, t2);
|
||||
nearT = std::max(t1, nearT);
|
||||
farT = std::min(t2, farT);
|
||||
|
||||
if (nearT > farT)
|
||||
if (!(nearT <= farT))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,6 +250,26 @@ public:
|
|||
EAuto
|
||||
};
|
||||
|
||||
/// List of different rotation/flip types that can be passed to \ref rotateFlip()
|
||||
enum ERotateFlipType {
|
||||
ERotateNoneFlipNone = 0,
|
||||
ERotate180FlipXY = ERotateNoneFlipNone,
|
||||
ERotate90FlipNone = 1,
|
||||
ERotate270FlipXY = ERotate90FlipNone,
|
||||
ERotate180FlipNone = 2,
|
||||
ERotateNoneFlipXY = ERotate180FlipNone,
|
||||
ERotate270FlipNone = 3,
|
||||
ERotate90FlipXY = ERotate270FlipNone,
|
||||
ERotateNoneFlipX = 4,
|
||||
ERotate180FlipY = ERotateNoneFlipX,
|
||||
ERotate90FlipX = 5,
|
||||
ERotate270FlipY = ERotate90FlipX,
|
||||
ERotate180FlipX = 6,
|
||||
ERotateNoneFlipY = ERotate180FlipX,
|
||||
ERotate270FlipX = 7,
|
||||
ERotate90FlipY = ERotate270FlipX
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Create a bitmap of the specified type and allocate
|
||||
* the necessary amount of memory
|
||||
|
@ -320,6 +340,15 @@ public:
|
|||
/// Return whether this image has matching width and height
|
||||
inline bool isSquare() const { return m_size.x == m_size.y; }
|
||||
|
||||
/// Return whether this image has an alpha channel
|
||||
inline bool hasAlpha() const {
|
||||
return
|
||||
m_pixelFormat == ELuminanceAlpha ||
|
||||
m_pixelFormat == ERGBA ||
|
||||
m_pixelFormat == EXYZA ||
|
||||
m_pixelFormat == ESpectrumAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the number bits per component
|
||||
*
|
||||
|
@ -393,17 +422,8 @@ public:
|
|||
/// Draw a rectangle with the specified position and size
|
||||
void drawRect(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
||||
|
||||
/**
|
||||
* \brief Color balancing: apply the given scale factors to the
|
||||
* red, green, and blue channels of the image
|
||||
*
|
||||
* When the image is not an \c EFloat16, \c EFloat32, or
|
||||
* \c EFloat64-based RGB/RGBA image, the function throws an exception
|
||||
*/
|
||||
void colorBalance(Float r, Float g, Float b);
|
||||
|
||||
/// Draw a filled rectangle with the specified position and size
|
||||
void fill(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
||||
void fillRect(Point2i offset, Vector2i size, const Spectrum &value);
|
||||
|
||||
/// Bitmap equality operator (useful for unit-tests etc.)
|
||||
bool operator==(const Bitmap &bitmap) const;
|
||||
|
@ -688,6 +708,9 @@ public:
|
|||
/// Vertically flip the image contents
|
||||
void flipVertically();
|
||||
|
||||
/// Perform the specified rotatation & flip operation
|
||||
ref<Bitmap> rotateFlip(ERotateFlipType type) const;
|
||||
|
||||
/**
|
||||
* \brief Accumulate the contents of another bitmap into the
|
||||
* region of the specified offset
|
||||
|
@ -699,7 +722,43 @@ public:
|
|||
* use different component formats or channels, or when the
|
||||
* component format is \ref EBitmask.
|
||||
*/
|
||||
void accumulate(const Bitmap *bitmap, const Point2i &offset);
|
||||
void accumulate(const Bitmap *bitmap, Point2i sourceOffset,
|
||||
Point2i targetOffset, Vector2i size);
|
||||
|
||||
/**
|
||||
* \brief Color balancing: apply the given scale factors to the
|
||||
* red, green, and blue channels of the image
|
||||
*
|
||||
* When the image is not an \c EFloat16, \c EFloat32, or
|
||||
* \c EFloat64-based RGB/RGBA image, the function throws an exception
|
||||
*/
|
||||
void colorBalance(Float r, Float g, Float b);
|
||||
|
||||
/**
|
||||
* Apply a color transformation matrix to the contents of the bitmap
|
||||
*
|
||||
* The implementation assumes that the contents have the
|
||||
* RGB, RGBA, XYZ, or XYZA pixel format and a floating point
|
||||
* component format.
|
||||
*/
|
||||
void applyMatrix(Float matrix[3][3]);
|
||||
|
||||
/**
|
||||
* \brief Accumulate the contents of another bitmap into the
|
||||
* region of the specified offset
|
||||
*
|
||||
* This convenience function calls the main <tt>accumulate()</tt>
|
||||
* implementation with <tt>size</tt> set to <tt>bitmap->getSize()</tt>
|
||||
* and <tt>sourceOffset</tt> set to zero. Out-of-bounds regions are
|
||||
* ignored. It is assumed that <tt>bitmap != this</tt>.
|
||||
*
|
||||
* \remark This function throws an exception when the bitmaps
|
||||
* use different component formats or channels, or when the
|
||||
* component format is \ref EBitmask.
|
||||
*/
|
||||
inline void accumulate(const Bitmap *bitmap, Point2i targetOffset) {
|
||||
accumulate(bitmap, Point2i(0), targetOffset, bitmap->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Up- or down-sample this image to a different resolution
|
||||
|
@ -747,25 +806,23 @@ public:
|
|||
inline void setGamma(Float gamma) { m_gamma = gamma; }
|
||||
|
||||
/// Set a string-valued metadata field
|
||||
void setString(const std::string &key, const std::string &value);
|
||||
inline void setMetadataString(const std::string &key, const std::string &value) {
|
||||
m_metadata.setString(key, value);
|
||||
}
|
||||
|
||||
/// Return a string-valued metadata field
|
||||
std::string getString(const std::string &key) const;
|
||||
|
||||
/// Return a map of all present metadata
|
||||
inline std::map<std::string, std::string> &getMetadata() {
|
||||
return m_metadata;
|
||||
inline std::string getMetadataString(const std::string &key) const {
|
||||
return m_metadata.getAsString(key);
|
||||
}
|
||||
|
||||
/// Return a map of all present metadata (const version)
|
||||
inline const std::map<std::string, std::string> &getMetadata() const {
|
||||
return m_metadata;
|
||||
}
|
||||
/// Return a \ref Properties object containing the image metadata
|
||||
inline Properties &getMetadata() { return m_metadata; }
|
||||
|
||||
/// Set the metadata associated with the bitmap
|
||||
inline void setMetadata(const std::map<std::string, std::string> &metadata) {
|
||||
m_metadata = metadata;
|
||||
}
|
||||
/// Return a \ref Properties object containing the image metadata (const version)
|
||||
inline const Properties &getMetadata() const { return m_metadata; }
|
||||
|
||||
/// Set the a \ref Properties object containing the image metadata
|
||||
inline void setMetadata(const Properties &metadata) { m_metadata = metadata; }
|
||||
|
||||
//! @}
|
||||
// ======================================================================
|
||||
|
@ -883,9 +940,9 @@ protected:
|
|||
EComponentFormat m_componentFormat;
|
||||
Vector2i m_size;
|
||||
uint8_t *m_data;
|
||||
std::map<std::string, std::string> m_metadata;
|
||||
Float m_gamma;
|
||||
int m_channelCount;
|
||||
Properties m_metadata;
|
||||
};
|
||||
|
||||
/** \brief Bitmap format conversion helper class
|
||||
|
|
|
@ -50,9 +50,13 @@
|
|||
#if defined(__WINDOWS__)
|
||||
#define ONE_MINUS_EPS_FLT 0.999999940395355225f
|
||||
#define ONE_MINUS_EPS_DBL 0.999999999999999888
|
||||
#define RCPOVERFLOW_FLT 2.93873587705571876e-39f
|
||||
#define RCPOVERFLOW_DBL 5.56268464626800345e-309
|
||||
#else
|
||||
#define ONE_MINUS_EPS_FLT 0x1.fffffep-1f
|
||||
#define ONE_MINUS_EPS_DBL 0x1.fffffffffffff7p-1
|
||||
#define RCPOVERFLOW_FLT 0x1p-128f
|
||||
#define RCPOVERFLOW_DBL 0x1p-1024
|
||||
#endif
|
||||
|
||||
#ifdef SINGLE_PRECISION
|
||||
|
@ -64,6 +68,7 @@
|
|||
#define SQRT_TWO 1.41421356237309504880f
|
||||
#define INV_SQRT_TWO 0.70710678118654752440f
|
||||
#define ONE_MINUS_EPS ONE_MINUS_EPS_FLT
|
||||
#define RCPOVERFLOW RCPOVERFLOW_FLT
|
||||
#else
|
||||
#define M_E 2.71828182845904523536
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
@ -73,5 +78,6 @@
|
|||
#define SQRT_TWO 1.41421356237309504880
|
||||
#define INV_SQRT_TWO 0.70710678118654752440
|
||||
#define ONE_MINUS_EPS ONE_MINUS_EPS_DBL
|
||||
#define RCPOVERFLOW RCPOVERFLOW_DBL
|
||||
#endif
|
||||
#endif /* __MITSUBA_CORE_CONSTANTS_H */
|
||||
|
|
|
@ -84,12 +84,24 @@ struct Frame {
|
|||
return s * v.x + t * v.y + n * v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the squared cosine of the angle between the normal and v */
|
||||
inline static Float cosTheta2(const Vector &v) {
|
||||
return v.z * v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the cosine of the angle between the normal and v */
|
||||
inline static Float cosTheta(const Vector &v) {
|
||||
return v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the squared sine of the angle between the normal and v */
|
||||
inline static Float sinTheta2(const Vector &v) {
|
||||
return 1.0f - v.z * v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the sine of the angle between the normal and v */
|
||||
inline static Float sinTheta(const Vector &v) {
|
||||
|
@ -109,9 +121,12 @@ struct Frame {
|
|||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the squared sine of the angle between the normal and v */
|
||||
inline static Float sinTheta2(const Vector &v) {
|
||||
return 1.0f - v.z * v.z;
|
||||
* system, return the squared tangent of the angle between the normal and v */
|
||||
inline static Float tanTheta2(const Vector &v) {
|
||||
Float temp = 1 - v.z*v.z;
|
||||
if (temp <= 0.0f)
|
||||
return 0.0f;
|
||||
return temp / (v.z * v.z);
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
struct AABB;
|
||||
class AbstractAnimationTrack;
|
||||
template <typename T> class AnimationTrack;
|
||||
class AnimatedTransform;
|
||||
class Appender;
|
||||
class Bitmap;
|
||||
class BlackBodySpectrum;
|
||||
|
@ -163,6 +166,11 @@ class WorkResult;
|
|||
class WorkUnit;
|
||||
class ZStream;
|
||||
|
||||
typedef AnimationTrack<Float> FloatTrack;
|
||||
typedef AnimationTrack<Quaternion> QuatTrack;
|
||||
typedef AnimationTrack<Vector> VectorTrack;
|
||||
typedef AnimationTrack<Point> PointTrack;
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#if BOOST_VERSION >= 105000
|
||||
|
|
|
@ -33,8 +33,11 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/// Write a Log message to the console (to be used within subclasses of <tt>Object</tt>)
|
||||
#define Log(level, fmt, ...) do { \
|
||||
mitsuba::Logger *logger = mitsuba::Thread::getThread()->getLogger(); \
|
||||
if (level >= logger->getLogLevel()) \
|
||||
mitsuba::Thread *thread = mitsuba::Thread::getThread(); \
|
||||
if (EXPECT_NOT_TAKEN(thread == NULL)) \
|
||||
throw std::runtime_error("Null thread pointer"); \
|
||||
mitsuba::Logger *logger = thread->getLogger(); \
|
||||
if (logger != NULL && level >= logger->getLogLevel()) \
|
||||
logger->log(level, m_theClass, \
|
||||
__FILE__, __LINE__, fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
@ -44,8 +47,11 @@ MTS_NAMESPACE_BEGIN
|
|||
* outside of classes that derive from Object)
|
||||
*/
|
||||
#define SLog(level, fmt, ...) do { \
|
||||
mitsuba::Logger *logger = mitsuba::Thread::getThread()->getLogger(); \
|
||||
if (level >= logger->getLogLevel()) \
|
||||
mitsuba::Thread *thread = mitsuba::Thread::getThread(); \
|
||||
if (EXPECT_NOT_TAKEN(thread == NULL)) \
|
||||
throw std::runtime_error("Null thread pointer"); \
|
||||
mitsuba::Logger *logger = thread->getLogger(); \
|
||||
if (logger != NULL && level >= logger->getLogLevel()) \
|
||||
logger->log(level, NULL, \
|
||||
__FILE__, __LINE__, fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
|
|
@ -31,7 +31,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \brief Generic LRU cache implementation
|
||||
*
|
||||
* Based on the bimap implementation by Tim Day
|
||||
* (http://www.bottlenose.demon.co.uk/article/lru.pdf).
|
||||
* (http://timday.bitbucket.org/lru.html).
|
||||
*
|
||||
* This cache does not support multithreading out of the box -- it
|
||||
* will need to be protected using some form of locking mechanism.
|
||||
|
|
|
@ -17,94 +17,12 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#if !defined(__MITSUBA_CORE_STL_H_)
|
||||
#define __MITSUBA_CORE_STL_H_
|
||||
|
||||
/* Include some SGI STL extensions, which might be missing */
|
||||
#ifdef __GNUC__
|
||||
#include <ext/functional>
|
||||
using __gnu_cxx::select2nd;
|
||||
using __gnu_cxx::compose1;
|
||||
#else
|
||||
#include <functional>
|
||||
#if !defined(__MITSUBA_CORE_MATH_H_)
|
||||
#define __MITSUBA_CORE_MATH_H_
|
||||
|
||||
/// \cond
|
||||
// (Don't include in the documentation)
|
||||
namespace std {
|
||||
template <class _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> {
|
||||
const typename _Pair::first_type& operator()(const _Pair& __x) const {
|
||||
return __x.first;
|
||||
}
|
||||
};
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
template <class _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> {
|
||||
const typename _Pair::second_type& operator()(const _Pair& __x) const {
|
||||
return __x.second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Pair> struct select1st : public _Select1st<_Pair> {};
|
||||
template <class _Pair> struct select2nd : public _Select2nd<_Pair> {};
|
||||
|
||||
template <class _Operation1, class _Operation2> class unary_compose : public unary_function<typename _Operation2::argument_type, typename _Operation1::result_type> {
|
||||
protected:
|
||||
_Operation1 _M_fn1;
|
||||
_Operation2 _M_fn2;
|
||||
public:
|
||||
unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {}
|
||||
typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const {
|
||||
return _M_fn1(_M_fn2(__x));
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Operation1, class _Operation2> inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) {
|
||||
return unary_compose<_Operation1,_Operation2>(__fn1, __fn2);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <float.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
|
||||
inline char tolower(char c) {
|
||||
return ::tolower(c);
|
||||
}
|
||||
|
||||
inline char toupper(char c) {
|
||||
return ::toupper(c);
|
||||
}
|
||||
|
||||
inline bool isnan(float f) {
|
||||
return _isnan(f);
|
||||
}
|
||||
|
||||
inline bool isnan(double f) {
|
||||
return _isnan(f);
|
||||
}
|
||||
|
||||
inline bool isfinite(float f) {
|
||||
return _finite(f);
|
||||
}
|
||||
|
||||
inline bool isfinite(double f) {
|
||||
return _finite(f);
|
||||
}
|
||||
|
||||
inline bool isinf(float f) {
|
||||
return !_finite(f);
|
||||
}
|
||||
|
||||
inline bool isinf(double f) {
|
||||
return !_finite(f);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
using std::select2nd;
|
||||
using std::compose1;
|
||||
#endif
|
||||
|
||||
namespace mitsuba {
|
||||
namespace math {
|
||||
#if defined(__LINUX__) && defined(__x86_64__)
|
||||
/*
|
||||
|
@ -211,7 +129,8 @@ namespace math {
|
|||
#endif
|
||||
}
|
||||
}; /* namespace math */
|
||||
}; /* namespace mitsuba */
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
extern "C" {
|
||||
|
@ -219,5 +138,5 @@ extern "C" {
|
|||
extern MTS_EXPORT_CORE double nextafter(double x, double y);
|
||||
};
|
||||
#endif
|
||||
/// @endcond
|
||||
#endif /* __MITSUBA_CORE_STL_H_ */
|
||||
|
||||
#endif /* __MITSUBA_CORE_MATH_H_ */
|
|
@ -491,7 +491,7 @@ public:
|
|||
/// Compute the inverse (Faster than Matrix::invert)
|
||||
FINLINE bool invert(Matrix2x2 &target) const {
|
||||
Float det = m[0][0]*m[1][1] - m[0][1]*m[1][0];
|
||||
if (det == 0)
|
||||
if (std::abs(det) <= RCPOVERFLOW)
|
||||
return false;
|
||||
Float invDet = 1/det;
|
||||
target.m[0][0] = m[1][1] * invDet;
|
||||
|
|
|
@ -70,6 +70,10 @@ struct Normal : public TVector3<Float> {
|
|||
}
|
||||
};
|
||||
|
||||
inline Normal normalize(const Normal &n) {
|
||||
return n / n.length();
|
||||
}
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __MITSUBA_CORE_NORMAL_H_ */
|
||||
|
|
|
@ -140,7 +140,7 @@ public:
|
|||
perm[i] = i;
|
||||
|
||||
/* Build the kd-tree and compute a suitable permutation of the elements */
|
||||
m_root = build(m_aabb, 0, &perm[0], &temp[0], &perm[0], &perm[m_items.size()]);
|
||||
m_root = build(m_aabb, 0, &perm[0], &temp[0], &perm[0], &perm[0] + m_items.size());
|
||||
|
||||
/* Apply the permutation */
|
||||
permute_inplace(&m_items[0], perm);
|
||||
|
|
|
@ -189,6 +189,62 @@ extern MTS_EXPORT_CORE void __mts_set_appdefaults();
|
|||
#define MTS_AUTORELEASE_BEGIN()
|
||||
#define MTS_AUTORELEASE_END()
|
||||
#endif
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
|
||||
/// \cond
|
||||
// Try to make MSVC++ behave a bit more like C++
|
||||
// with an underlying C99 implementation
|
||||
// (and don't include this in the documentation)
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
|
||||
namespace mitsuba {
|
||||
#if defined(__64BIT__)
|
||||
typedef long long ssize_t;
|
||||
#else
|
||||
typedef long ssize_t;
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace std {
|
||||
inline char tolower(char c) {
|
||||
return ::tolower(c);
|
||||
}
|
||||
|
||||
inline char toupper(char c) {
|
||||
return ::toupper(c);
|
||||
}
|
||||
|
||||
inline bool isnan(float f) {
|
||||
return _isnan(f);
|
||||
}
|
||||
|
||||
inline bool isnan(double f) {
|
||||
return _isnan(f);
|
||||
}
|
||||
|
||||
inline bool isfinite(float f) {
|
||||
return _finite(f);
|
||||
}
|
||||
|
||||
inline bool isfinite(double f) {
|
||||
return _finite(f);
|
||||
}
|
||||
|
||||
inline bool isinf(float f) {
|
||||
return !_finite(f);
|
||||
}
|
||||
|
||||
inline bool isinf(double f) {
|
||||
return !_finite(f);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __MITSUBA_CORE_PLATFORM_H_ */
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
EVector,
|
||||
/// 4x4 transform for homogeneous coordinates
|
||||
ETransform,
|
||||
/// An animated 4x4 transformation
|
||||
EAnimatedTransform,
|
||||
/// Discretized color spectrum
|
||||
ESpectrum,
|
||||
/// Arbitrary-length string
|
||||
|
@ -71,6 +73,14 @@ public:
|
|||
struct Data {
|
||||
uint8_t *ptr;
|
||||
size_t size;
|
||||
|
||||
inline bool operator==(const Data &d) const {
|
||||
return ptr == d.ptr && size == d.size;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Data &d) const {
|
||||
return !operator==(d);
|
||||
}
|
||||
};
|
||||
|
||||
/// Construct an empty property container
|
||||
|
@ -144,6 +154,15 @@ public:
|
|||
/// Get a linear transformation (with default)
|
||||
Transform getTransform(const std::string &name, const Transform &defVal) const;
|
||||
|
||||
/// Set an animated linear transformation
|
||||
void setAnimatedTransform(const std::string &name, const AnimatedTransform *value, bool warnDuplicates = true);
|
||||
/// Get an animated linear transformation
|
||||
ref<const AnimatedTransform> getAnimatedTransform(const std::string &name) const;
|
||||
/// Get an animated linear transformation (with default)
|
||||
ref<const AnimatedTransform> getAnimatedTransform(const std::string &name, const AnimatedTransform *defVal) const;
|
||||
/// Get an animated linear transformation (with default)
|
||||
ref<const AnimatedTransform> getAnimatedTransform(const std::string &name, const Transform &defVal) const;
|
||||
|
||||
/// Set a spectral power distribution
|
||||
void setSpectrum(const std::string &name, const Spectrum &value, bool warnDuplicates = true);
|
||||
/// Get a spectral power distribution
|
||||
|
@ -172,6 +191,15 @@ public:
|
|||
/// Get a string (with default)
|
||||
std::string getString(const std::string &name, const std::string &defVal) const;
|
||||
|
||||
/// Return one of the parameters (converting it to a string if necessary)
|
||||
std::string getAsString(const std::string &name) const;
|
||||
/// Return one of the parameters (converting it to a string if necessary, with default value)
|
||||
std::string getAsString(const std::string &name, const std::string &defVal) const;
|
||||
|
||||
/// Copy an attribute from another Properties object and potentially rename it
|
||||
void copyAttribute(const Properties &properties,
|
||||
const std::string &sourceName, const std::string &targetName);
|
||||
|
||||
/// Store an array containing the names of all stored properties
|
||||
void putPropertyNames(std::vector<std::string> &results) const;
|
||||
|
||||
|
@ -206,6 +234,14 @@ public:
|
|||
/// Assignment operator
|
||||
void operator=(const Properties &props);
|
||||
|
||||
/// Equality comparison operator
|
||||
bool operator==(const Properties &props) const;
|
||||
|
||||
/// Inequality comparision operator
|
||||
inline bool operator!=(const Properties &props) const {
|
||||
return !operator==(props);
|
||||
}
|
||||
|
||||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
private:
|
||||
|
|
|
@ -40,7 +40,7 @@ extern const int MTS_EXPORT_CORE primeTable[primeTableSize];
|
|||
/// Van der Corput radical inverse in base 2 with single precision
|
||||
inline float radicalInverse2Single(uint32_t n, uint32_t scramble = 0U) {
|
||||
/* Efficiently reverse the bits in 'n' using binary operations */
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
|
||||
n = __builtin_bswap32(n);
|
||||
#else
|
||||
n = (n << 16) | (n >> 16);
|
||||
|
@ -59,7 +59,7 @@ inline float radicalInverse2Single(uint32_t n, uint32_t scramble = 0U) {
|
|||
/// Van der Corput radical inverse in base 2 with double precision
|
||||
inline double radicalInverse2Double(uint64_t n, uint64_t scramble = 0ULL) {
|
||||
/* Efficiently reverse the bits in 'n' using binary operations */
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
|
||||
n = __builtin_bswap64(n);
|
||||
#else
|
||||
n = (n << 32) | (n >> 32);
|
||||
|
@ -159,9 +159,9 @@ inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
|
|||
single precision number in [1,2) and subtract 1. */
|
||||
union {
|
||||
uint64_t u;
|
||||
float f;
|
||||
double f;
|
||||
} x;
|
||||
x.u = (sampleTEA(v0, v1, rounds) >> 12) | 0x3ff0000000000000;
|
||||
x.u = (sampleTEA(v0, v1, rounds) >> 12) | 0x3ff0000000000000ULL;
|
||||
return x.f - 1.0;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,12 @@ extern MTS_EXPORT_CORE float legendreP(int l, float x);
|
|||
/// Evaluate the l-th Legendre polynomial using recurrence (double precision)
|
||||
extern MTS_EXPORT_CORE double legendreP(int l, double x);
|
||||
|
||||
/// Evaluate an associated Legendre polynomial using recurrence (single precision)
|
||||
extern MTS_EXPORT_CORE float legendreP(int l, int m, float x);
|
||||
|
||||
/// Evaluate an associated Legendre polynomial using recurrence (double precision)
|
||||
extern MTS_EXPORT_CORE double legendreP(int l, int m, double x);
|
||||
|
||||
/// Evaluate the l-th Legendre polynomial and its derivative using recurrence (single precision)
|
||||
extern MTS_EXPORT_CORE std::pair<float, float> legendrePD(int l, float x);
|
||||
|
||||
|
|
|
@ -84,6 +84,11 @@ template <typename T> struct TQuaternion {
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// Unary negation operator
|
||||
TQuaternion operator-() const {
|
||||
return TQuaternion(-v, -w);
|
||||
}
|
||||
|
||||
/// Multiply the quaternion by the given scalar and return the result
|
||||
TQuaternion operator*(T f) const {
|
||||
return TQuaternion(v*f, w*f);
|
||||
|
@ -132,12 +137,17 @@ template <typename T> struct TQuaternion {
|
|||
|
||||
/// Equality test
|
||||
bool operator==(const TQuaternion &q) const {
|
||||
return v == q.v && v.w == q.w;
|
||||
return v == q.v && w == q.w;
|
||||
}
|
||||
|
||||
/// Inequality test
|
||||
bool operator!=(const TQuaternion &q) const {
|
||||
return v != q.v || v.w != q.w;
|
||||
return v != q.v || w != q.w;
|
||||
}
|
||||
|
||||
/// Identity test
|
||||
bool isIdentity() const {
|
||||
return v.isZero() && w == 1;
|
||||
}
|
||||
|
||||
/// Return the rotation axis of this quaternion
|
||||
|
@ -216,39 +226,41 @@ template <typename T> struct TQuaternion {
|
|||
}
|
||||
}
|
||||
|
||||
inline static TQuaternion fromTransform(const Transform &trafo) {
|
||||
return fromMatrix(trafo.getMatrix());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Construct an unit quaternion matching the supplied
|
||||
* rotation matrix.
|
||||
*/
|
||||
static TQuaternion fromTransform(const Transform trafo) {
|
||||
/// Implementation from PBRT
|
||||
const Matrix4x4 &m = trafo.getMatrix();
|
||||
T trace = m.m[0][0] + m.m[1][1] + m.m[2][2];
|
||||
static TQuaternion fromMatrix(const Matrix4x4 &m) {
|
||||
// Implementation from PBRT, originally based on the matrix
|
||||
// and quaternion FAQ (http://www.j3d.org/matrix_faq/matrfaq_latest.html)
|
||||
T trace = m(0, 0) + m(1, 1) + m(2, 2);
|
||||
TVector3<T> v; T w;
|
||||
if (trace > 0.f) {
|
||||
// Compute w from matrix trace, then xyz
|
||||
// 4w^2 = m[0][0] + m[1][1] + m[2][2] + m[3][3] (but m[3][3] == 1)
|
||||
|
||||
if (trace > Epsilon) {
|
||||
T s = std::sqrt(trace + 1.0f);
|
||||
w = s / 2.0f;
|
||||
w = s * 0.5f;
|
||||
s = 0.5f / s;
|
||||
v.x = (m.m[2][1] - m.m[1][2]) * s;
|
||||
v.y = (m.m[0][2] - m.m[2][0]) * s;
|
||||
v.z = (m.m[1][0] - m.m[0][1]) * s;
|
||||
v.x = (m(2, 1) - m(1, 2)) * s;
|
||||
v.y = (m(0, 2) - m(2, 0)) * s;
|
||||
v.z = (m(1, 0) - m(0, 1)) * s;
|
||||
} else {
|
||||
// Compute largest of $x$, $y$, or $z$, then remaining components
|
||||
const int nxt[3] = {1, 2, 0};
|
||||
T q[3];
|
||||
int i = 0;
|
||||
if (m.m[1][1] > m.m[0][0]) i = 1;
|
||||
if (m.m[2][2] > m.m[i][i]) i = 2;
|
||||
if (m(1, 1) > m(0, 0)) i = 1;
|
||||
if (m(2, 2) > m(i, i)) i = 2;
|
||||
int j = nxt[i];
|
||||
int k = nxt[j];
|
||||
T s = std::sqrt((m.m[i][i] - (m.m[j][j] + m.m[k][k])) + 1.0);
|
||||
T s = std::sqrt((m(i, i) - (m(j, j) + m(k, k))) + 1.0f);
|
||||
q[i] = s * 0.5f;
|
||||
if (s != 0.f) s = 0.5f / s;
|
||||
w = (m.m[k][j] - m.m[j][k]) * s;
|
||||
q[j] = (m.m[j][i] + m.m[i][j]) * s;
|
||||
q[k] = (m.m[k][i] + m.m[i][k]) * s;
|
||||
w = (m(k, j) - m(j, k)) * s;
|
||||
q[j] = (m(j, i) + m(i, j)) * s;
|
||||
q[k] = (m(k, i) + m(i, k)) * s;
|
||||
v.x = q[0];
|
||||
v.y = q[1];
|
||||
v.z = q[2];
|
||||
|
@ -342,8 +354,15 @@ template <typename T> inline TQuaternion<T> normalize(const TQuaternion<T> &q) {
|
|||
}
|
||||
|
||||
template <typename T> inline TQuaternion<T> slerp(const TQuaternion<T> &q1,
|
||||
const TQuaternion<T> &q2, Float t) {
|
||||
const TQuaternion<T> &_q2, Float t) {
|
||||
TQuaternion<T> q2(_q2);
|
||||
|
||||
T cosTheta = dot(q1, q2);
|
||||
if (cosTheta < 0) {
|
||||
/* Take the short way! */
|
||||
q2 = -q2;
|
||||
cosTheta = -cosTheta;
|
||||
}
|
||||
if (cosTheta > .9995f) {
|
||||
// Revert to plain linear interpolation
|
||||
return normalize(q1 * (1.0f - t) + q2 * t);
|
||||
|
|
|
@ -417,8 +417,10 @@ public:
|
|||
*
|
||||
* Note that the resource's won't be removed until all processes using
|
||||
* it have terminated)
|
||||
*
|
||||
* \return \c false if the resource could not be found
|
||||
*/
|
||||
void unregisterResource(int id);
|
||||
bool unregisterResource(int id);
|
||||
|
||||
/**
|
||||
* \brief Return the ID of a registered resource
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define __MITSUBA_CORE_SHVECTOR_H_
|
||||
|
||||
#include <mitsuba/mitsuba.h>
|
||||
#include <mitsuba/core/quad.h>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <numeric>
|
||||
|
||||
|
@ -273,12 +274,12 @@ public:
|
|||
|
||||
for (int l=0; l<m_bands; ++l) {
|
||||
for (int m=1; m<=l; ++m) {
|
||||
Float L = legendre(l, m, cosTheta) * normalization(l, m);
|
||||
Float L = legendreP(l, m, cosTheta) * normalization(l, m);
|
||||
operator()(l, -m) += value * SQRT_TWO * sinPhi[m-1] * L;
|
||||
operator()(l, m) += value * SQRT_TWO * cosPhi[m-1] * L;
|
||||
}
|
||||
|
||||
operator()(l, 0) += value * legendre(l, 0, cosTheta) * normalization(l, 0);
|
||||
operator()(l, 0) += value * legendreP(l, 0, cosTheta) * normalization(l, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,9 +322,6 @@ public:
|
|||
return error/denom;
|
||||
}
|
||||
|
||||
/// Evaluate an associated Legendre polynomial using the usual recurrence formulae
|
||||
static Float legendre(int l, int m, Float x);
|
||||
|
||||
/// Return a normalization coefficient
|
||||
inline static Float normalization(int l, int m) {
|
||||
if (l < SH_NORMTBL_SIZE)
|
||||
|
|
|
@ -440,7 +440,7 @@ public:
|
|||
|
||||
/// Divide by a scalar
|
||||
inline friend TSpectrum operator/(Scalar f, TSpectrum &spec) {
|
||||
return spec / f;
|
||||
return TSpectrum(f) / spec;
|
||||
}
|
||||
|
||||
/// Divide by a scalar
|
||||
|
@ -493,6 +493,14 @@ public:
|
|||
return value;
|
||||
}
|
||||
|
||||
/// Component-wise square root
|
||||
inline TSpectrum safe_sqrt() const {
|
||||
TSpectrum value;
|
||||
for (int i=0; i<N; i++)
|
||||
value.s[i] = math::safe_sqrt(s[i]);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Component-wise exponentation
|
||||
inline TSpectrum exp() const {
|
||||
TSpectrum value;
|
||||
|
@ -710,7 +718,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Convert XYZ tristimulus into a plausible spectral
|
||||
* power distribution
|
||||
* reflectance or spectral power distribution
|
||||
*
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* information on how to solve this highly under-constrained problem.
|
||||
|
@ -719,6 +727,34 @@ public:
|
|||
void fromXYZ(Float x, Float y, Float z,
|
||||
EConversionIntent intent = EReflectance);
|
||||
|
||||
/**
|
||||
* \brief Convert from a spectral power distribution to
|
||||
* the perceptually uniform IPT color space by Ebner and Fairchild
|
||||
*
|
||||
* This is useful e.g. for computing color differences.
|
||||
* \c I encodes intensity, \c P (protan) roughly encodes
|
||||
* red-green color opponency, and \c T (tritan) encodes
|
||||
* blue-red color opponency. For normalized input, the
|
||||
* range of attainable values is given by
|
||||
* \f I\in $[0,1], P,T\in [-1,1]\f$.
|
||||
*
|
||||
* In the Python API, this function returns a 3-tuple
|
||||
* with the result of the operation.
|
||||
*/
|
||||
void toIPT(Float &I, Float &P, Float &T) const;
|
||||
|
||||
/**
|
||||
* \brief Convert a color value represented in the IPT
|
||||
* space into a plausible spectral reflectance or
|
||||
* spectral power distribution.
|
||||
*
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* information on how to solve this highly under-constrained problem.
|
||||
* The default is \ref EReflectance.
|
||||
*/
|
||||
void fromIPT(Float I, Float P, Float T,
|
||||
EConversionIntent intent = EReflectance);
|
||||
|
||||
#if SPECTRUM_SAMPLES == 3
|
||||
/**
|
||||
* \brief Convert to linear RGB
|
||||
|
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2012 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License Version 3
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Mitsuba is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#if !defined(__MITSUBA_CORE_SPLINE_H_)
|
||||
#define __MITSUBA_CORE_SPLINE_H_
|
||||
|
||||
#include <mitsuba/mitsuba.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/*! \addtogroup libcore */
|
||||
/*! @{ */
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
//! @{ \name Functions for evaluating and sampling Catmull-Rom splines
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a uniformly sampled 1D function
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* \param values
|
||||
* Floating point array containing \c size regularly spaced evaluations
|
||||
* in the range [\c min,\c max] of the function to be approximated.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \param min
|
||||
* Position of the first knot
|
||||
* \param max
|
||||
* Position of the last knot
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c x is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt>
|
||||
* and \c x lies outside of [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp1D(Float x, const Float *values,
|
||||
size_t size, Float min, Float max, bool extrapolate = false);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a \a nonuniformly sampled 1D function
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Floating point array containing \c size nonuniformly spaced values
|
||||
* denoting positions the where the function to be interpolated was evaluated.
|
||||
* They must be provided in \a increasing order.
|
||||
* \param values
|
||||
* Floating point array containing function evaluations matched to
|
||||
* the entries of \c nodes.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c x is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt>
|
||||
* and \c x lies outside of \a [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp1DN(Float x, const Float *nodes,
|
||||
const Float *values, size_t size, bool extrapolate = false);
|
||||
|
||||
/**
|
||||
* \brief Computes the definite integral over a segment of a uniformly
|
||||
* sampled 1D Catmull-Rom spline interpolant
|
||||
*
|
||||
* This is useful for sampling spline segments as part of an importance
|
||||
* sampling scheme (in conjunction with \ref sampleCubicInterp1D)
|
||||
*
|
||||
* \param idx
|
||||
* Denotes the desires spline segment (must be between 0 and size-2)
|
||||
* \param values
|
||||
* Floating point array containing \c size regularly spaced evaluations
|
||||
* in the range [\c min,\c max] of the function to be approximated.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \param min
|
||||
* Position of the first knot
|
||||
* \param max
|
||||
* Position of the last knot
|
||||
* \return
|
||||
* The definite integral over the specified segment
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float integrateCubicInterp1D(size_t idx,
|
||||
const Float *values, size_t size, Float min, Float max);
|
||||
|
||||
/**
|
||||
* \brief Computes the definite integral over a segment of a \a nonuniformly
|
||||
* sampled 1D Catmull-Rom spline interpolant
|
||||
*
|
||||
* This is useful for sampling spline segments as part of an importance
|
||||
* sampling scheme (in conjunction with \ref sampleCubicInterp1D)
|
||||
*
|
||||
* \param idx
|
||||
* Denotes the desires spline segment (must be between 0 and size-2)
|
||||
* \param nodes
|
||||
* Floating point array containing \c size nonuniformly spaced values
|
||||
* denoting positions the where the function to be interpolated was evaluated.
|
||||
* They must be provided in \a increasing order.
|
||||
* \param values
|
||||
* Floating point array containing function evaluations matched to
|
||||
* the entries of \c nodes.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \return
|
||||
* The definite integral over the specified segment
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float integrateCubicInterp1DN(size_t idx,
|
||||
const Float *nodes, const Float *values, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Importance sample a segment of a uniformly sampled 1D Catmull-Rom
|
||||
* spline interpolant
|
||||
*
|
||||
* \param idx
|
||||
* Denotes the desires spline segment (must be between 0 and size-2)
|
||||
* \param values
|
||||
* Floating point array containing \c size regularly spaced evaluations
|
||||
* in the range [\c min,\c max] of the function to be approximated.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \param min
|
||||
* Position of the first knot
|
||||
* \param max
|
||||
* Position of the last knot
|
||||
* \param sample
|
||||
* A uniformly distributed random sample in the interval <tt>[0,1]</tt>
|
||||
* \param fval
|
||||
* If set to a non-NULL pointer, this argument will be used to return
|
||||
* the value of the spline at the sampled position
|
||||
* \return
|
||||
* The sampled position
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float sampleCubicInterp1D(size_t idx, Float *values,
|
||||
size_t size, Float min, Float max, Float sample, Float *fval = NULL);
|
||||
|
||||
/**
|
||||
* \brief Importance sample a segment of a \a nonuniformly sampled 1D Catmull-Rom
|
||||
* spline interpolant
|
||||
*
|
||||
* \param idx
|
||||
* Denotes the desires spline segment (must be between 0 and size-2)
|
||||
* \param nodes
|
||||
* Floating point array containing \c size nonuniformly spaced values
|
||||
* denoting positions the where the function to be interpolated was evaluated.
|
||||
* They must be provided in \a increasing order.
|
||||
* \param values
|
||||
* Floating point array containing function evaluations matched to
|
||||
* the entries of \c nodes.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array
|
||||
* \param sample
|
||||
* A uniformly distributed random sample in the interval <tt>[0,1]</tt>
|
||||
* \param fval
|
||||
* If set to a non-NULL pointer, this argument will be used to return
|
||||
* the value of the spline at the sampled position
|
||||
* \return
|
||||
* The sampled position
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float sampleCubicInterp1DN(size_t idx, Float *nodes,
|
||||
Float *values, size_t size, Float sample, Float *fval = NULL);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a uniformly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* patch.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param values
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array (along each dimension)
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c p is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt> and
|
||||
* \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp2D(const Point2 &p, const Float *values,
|
||||
const Size2 &size, const Point2 &min, const Point2 &max, bool extrapolate = false);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a \a nonuniformly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* When the underlying function is sampled on a regular grid, \ref evalCubicInterp2D()
|
||||
* should be preferred, since value lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param values
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing nonuniformly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array (along each dimension)
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c p is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt> and
|
||||
* \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp2DN(const Point2 &p, const Float **nodes,
|
||||
const Float *values, const Size2 &size, bool extrapolate = false);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a uniformly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point of the interpolant
|
||||
* \param values
|
||||
* A 3D floating point array of <tt>size.x*size.y*size.z</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array (along each dimension)
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c p is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt> and
|
||||
* \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp3D(const Point3 &p, const Float *values,
|
||||
const Size3 &size, const Point3 &min, const Point3 &max, bool extrapolate = false);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a \a nonuniformly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* When the underlying function is sampled on a regular grid, \ref evalCubicInterp3D()
|
||||
* should be preferred, since value lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param values
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing nonuniformly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param size
|
||||
* Denotes the size of the \c values array (along each dimension)
|
||||
* \param extrapolate
|
||||
* Extrapolate values when \c p is out of range? (default: \c false)
|
||||
* \return
|
||||
* The interpolated value or zero when <tt>extrapolate=false</tt>tt> and
|
||||
* \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float evalCubicInterp3DN(const Point3 &p, const Float **nodes,
|
||||
const Float *values, const Size3 &size, bool extrapolate = false);
|
||||
|
||||
//! @}
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/*! @} */
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __MITSUBA_CORE_SPLINE_H_ */
|
|
@ -153,30 +153,60 @@ public:
|
|||
/// Write an array of signed shorts (16 bit) to the stream
|
||||
void writeShortArray(const short *values, size_t size);
|
||||
|
||||
/// Write an array of known size of signed shorts (16 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeShortArray(const short (&values)[N]) {
|
||||
writeShortArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write an unsigned short (16 bit) to the stream
|
||||
void writeUShort(unsigned short value);
|
||||
|
||||
/// Write an array of unsigned shorts (16 bit) to the stream
|
||||
void writeUShortArray(const unsigned short *values, size_t size);
|
||||
|
||||
/// Write an array of known size of unsigned shorts (16 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeUShortArray(const unsigned short (&values)[N]) {
|
||||
writeUShortArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a signed int (32 bit) to the stream
|
||||
void writeInt(int value);
|
||||
|
||||
/// Write an array of signed ints (32 bit) to the stream
|
||||
void writeIntArray(const int *values, size_t size);
|
||||
|
||||
/// Write an array of known size of signed ints (32 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeIntArray(const int (&values)[N]) {
|
||||
writeIntArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write an unsigned int (32 bit) to the stream
|
||||
void writeUInt(unsigned int value);
|
||||
|
||||
/// Write an array of unsigned ints (32 bit) to the stream
|
||||
void writeUIntArray(const unsigned int *values, size_t size);
|
||||
|
||||
/// Write a signed int (32 bit) to the stream
|
||||
/// Write an array of known size of unsigned ints (32 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeUIntArray(const unsigned int (&values)[N]) {
|
||||
writeUIntArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a signed int (64 bit) to the stream
|
||||
void writeLong(int64_t value);
|
||||
|
||||
/// Write an array of signed ints (64 bit) to the stream
|
||||
void writeLongArray(const int64_t *values, size_t size);
|
||||
|
||||
/// Write an array of known size of signed ints (64 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeLongArray(const int64_t (&values)[N]) {
|
||||
writeLongArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write an unsigned int (64 bit) to the stream
|
||||
void writeULong(uint64_t value);
|
||||
|
||||
|
@ -186,6 +216,12 @@ public:
|
|||
/// Write an array of unsigned ints (64 bit) to the stream
|
||||
void writeULongArray(const uint64_t *values, size_t size);
|
||||
|
||||
/// Write an array of known size of unsigned ints (64 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeULongArray(const uint64_t (&values)[N]) {
|
||||
writeULongArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a signed character (8 bit) to the stream
|
||||
void writeChar(char value);
|
||||
|
||||
|
@ -195,24 +231,42 @@ public:
|
|||
/// Write a boolean (8 bit) to the stream
|
||||
inline void writeBool(bool value) { writeUChar(value); }
|
||||
|
||||
/// Write a half-precision halfing point number (16 bit) to the stream
|
||||
/// Write a half-precision floating point number (16 bit) to the stream
|
||||
void writeHalf(half value);
|
||||
|
||||
/// Write a half-precision halfing point array (16 bit) to the stream
|
||||
/// Write a half-precision floating point array (16 bit) to the stream
|
||||
void writeHalfArray(const half *data, size_t size);
|
||||
|
||||
/// Write a known size half-precision floating point array (16 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeHalfArray(const half (&values)[N]) {
|
||||
writeHalfArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a single-precision floating point number (32 bit) to the stream
|
||||
void writeSingle(float value);
|
||||
|
||||
/// Write a single-precision floating point array (32 bit) to the stream
|
||||
void writeSingleArray(const float *data, size_t size);
|
||||
|
||||
/// Write a known size single-precision floating point array (32 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeSingleArray(const float (&values)[N]) {
|
||||
writeSingleArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a double-precision floating point number (64 bit) to the stream
|
||||
void writeDouble(double value);
|
||||
|
||||
/// Write a double-precision floating point array (64 bit) to the stream
|
||||
void writeDoubleArray(const double *data, size_t size);
|
||||
|
||||
/// Write a known size double-precision floating point array (64 bit) to the stream
|
||||
template <size_t N>
|
||||
inline void writeDoubleArray(const double (&values)[N]) {
|
||||
writeDoubleArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a floating point number (configured precision) to the stream
|
||||
inline void writeFloat(Float value) {
|
||||
#ifdef SINGLE_PRECISION
|
||||
|
@ -231,6 +285,12 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Write a known size array of floating point values (configured precision) to the stream
|
||||
template <size_t N>
|
||||
inline void writeFloatArray(const Float (&values)[N]) {
|
||||
writeFloatArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Return whether we are at the end of the stream
|
||||
bool isEOF() const;
|
||||
|
||||
|
@ -246,30 +306,60 @@ public:
|
|||
/// Read an array of signed shorts (16 bit) from the stream
|
||||
void readShortArray(short *dest, size_t size);
|
||||
|
||||
/// Read an array of known size of signed shorts (16 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readShortArray(short (&values)[N]) {
|
||||
readShortArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read an unsigned short (16 bit) from the stream
|
||||
unsigned short readUShort();
|
||||
|
||||
/// Read an array of unsigned shorts (16 bit) from the stream
|
||||
void readUShortArray(unsigned short *dest, size_t size);
|
||||
|
||||
/// Read an array of known size of unsigned shorts (16 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readUShortArray(short (&values)[N]) {
|
||||
readUShortArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read a signed int (32 bit) from the stream
|
||||
int readInt();
|
||||
|
||||
/// Read an array of signed ints (32 bit) from the stream
|
||||
void readIntArray(int *dst, size_t size);
|
||||
|
||||
/// Read an array of known size of signed ints (32 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readIntArray(int (&values)[N]) {
|
||||
readIntArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read an unsigned int (32 bit) from the stream
|
||||
unsigned int readUInt();
|
||||
|
||||
/// Read an array of unsigned ints (32 bit) from the stream
|
||||
void readUIntArray(unsigned int *dest, size_t size);
|
||||
|
||||
/// Read an array of known size of unsigned ints (32 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readUIntArray(int (&values)[N]) {
|
||||
readUIntArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read a signed int (64 bit) from the stream
|
||||
int64_t readLong();
|
||||
|
||||
/// Read an array of signed ints (64 bit) from the stream
|
||||
void readLongArray(int64_t *dst, size_t size);
|
||||
|
||||
/// Read an array of known size of signed ints (64 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readLongArray(int64_t (&values)[N]) {
|
||||
readLongArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read an unsigned int (64 bit) from the stream
|
||||
uint64_t readULong();
|
||||
|
||||
|
@ -279,6 +369,12 @@ public:
|
|||
/// Read an array of unsigned ints (64 bit) from the stream
|
||||
void readULongArray(uint64_t *dst, size_t size);
|
||||
|
||||
/// Read an array of known size of unsigned ints (64 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readULongArray(uint64_t (&values)[N]) {
|
||||
readULongArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read a signed character (8 bit) from the stream
|
||||
char readChar();
|
||||
|
||||
|
@ -288,24 +384,42 @@ public:
|
|||
/// Read a boolean (8 bit) from the stream
|
||||
inline bool readBool() { return static_cast<bool> (readUChar()); }
|
||||
|
||||
/// Read a half-precision halfing point number (16 bit) from the stream
|
||||
/// Read a half-precision floating point number (16 bit) from the stream
|
||||
half readHalf();
|
||||
|
||||
/// Read a half-precision halfing point array (16 bit) from the stream
|
||||
/// Read a half-precision floating point array (16 bit) from the stream
|
||||
void readHalfArray(half *data, size_t size);
|
||||
|
||||
/// Read a known-size half-precision floating point array (16 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readHalfArray(half (&values)[N]) {
|
||||
readHalfArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read a single-precision floating point number (32 bit) from the stream
|
||||
float readSingle();
|
||||
|
||||
/// Read a single-precision floating point array (32 bit) from the stream
|
||||
void readSingleArray(float *data, size_t size);
|
||||
|
||||
/// Read a known-size single-precision floating point array (32 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readSingleArray(float (&values)[N]) {
|
||||
readSingleArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Read a double-precision floating point number (64 bit) from the stream
|
||||
double readDouble();
|
||||
|
||||
/// Read a double-precision floating point array (64 bit) from the stream
|
||||
void readDoubleArray(double *data, size_t size);
|
||||
|
||||
/// Read a known-size double-precision floating point array (64 bit) from the stream
|
||||
template <size_t N>
|
||||
inline void readDoubleArray(double (&values)[N]) {
|
||||
readDoubleArray(&values[0], N);
|
||||
}
|
||||
|
||||
/// Write a floating point number (configured precision) to the stream
|
||||
inline Float readFloat() {
|
||||
#ifdef SINGLE_PRECISION
|
||||
|
@ -324,6 +438,12 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Read a known-size array of floating point values (configured precision) to the stream
|
||||
template <size_t N>
|
||||
inline void readFloatArray(Float (&values)[N]) {
|
||||
readFloatArray(&values[0], N);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Copy content from this stream into another stream
|
||||
* \param stream Destination stream
|
||||
|
@ -351,12 +471,28 @@ public:
|
|||
*/
|
||||
template <typename T> void readArray(T *array, size_t count);
|
||||
|
||||
/**
|
||||
* \brief Read a known-size array from the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T, size_t N> inline void readArray(T (&arr)[N]) {
|
||||
readArray(&arr[0], N);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write an array to the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T> void writeArray(const T *array, size_t count);
|
||||
|
||||
/**
|
||||
* \brief Write a known-size array to the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T, size_t N> inline void writeArray(const T (&arr)[N]) {
|
||||
writeArray(&arr[0], N);
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
|
|
@ -185,6 +185,9 @@ extern MTS_EXPORT_CORE int mts_omp_get_thread_num();
|
|||
#define mts_omp_get_max_threads omp_get_max_threads
|
||||
#define mts_omp_get_thread_num omp_get_thread_num
|
||||
#endif
|
||||
#else
|
||||
#define mts_omp_get_max_threads() 1
|
||||
#define mts_omp_get_thread_num() 0
|
||||
#endif
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
|
|
@ -141,6 +141,7 @@ protected:
|
|||
}
|
||||
|
||||
inline static void destruct(void *data) {
|
||||
if (data)
|
||||
delete static_cast<ValueType *>(data);
|
||||
}
|
||||
protected:
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#if !defined(__MITSUBA_RENDER_TRACK_H_)
|
||||
#define __MITSUBA_RENDER_TRACK_H_
|
||||
#if !defined(__MITSUBA_CORE_TRACK_H_)
|
||||
#define __MITSUBA_CORE_TRACK_H_
|
||||
|
||||
#include <mitsuba/core/quat.h>
|
||||
#include <mitsuba/core/simplecache.h>
|
||||
#include <set>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -31,7 +32,7 @@ template <typename T> class AnimationTrack;
|
|||
* \brief Base class of animation tracks
|
||||
* \ingroup librender
|
||||
*/
|
||||
class MTS_EXPORT_RENDER AbstractAnimationTrack : public Object {
|
||||
class MTS_EXPORT_CORE AbstractAnimationTrack : public Object {
|
||||
template<typename T> friend class AnimationTrack;
|
||||
public:
|
||||
enum EType {
|
||||
|
@ -65,6 +66,9 @@ public:
|
|||
/// Serialize to a binary data stream
|
||||
virtual void serialize(Stream *stream) const = 0;
|
||||
|
||||
/// Clone this track
|
||||
virtual AbstractAnimationTrack *clone() const = 0;
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
AbstractAnimationTrack(EType type, size_t nKeyframes)
|
||||
|
@ -82,9 +86,9 @@ protected:
|
|||
*/
|
||||
template <typename T> class AnimationTrack : public AbstractAnimationTrack {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T ValueType;
|
||||
|
||||
AnimationTrack(EType type, size_t nKeyframes)
|
||||
AnimationTrack(EType type, size_t nKeyframes = 0)
|
||||
: AbstractAnimationTrack(type, nKeyframes), m_values(nKeyframes) { }
|
||||
|
||||
AnimationTrack(EType type, Stream *stream)
|
||||
|
@ -95,11 +99,44 @@ public:
|
|||
unserialize(stream, m_values[i]);
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
AnimationTrack(const AnimationTrack *track)
|
||||
: AbstractAnimationTrack(track->getType(), track->getSize()) {
|
||||
m_times = track->m_times;
|
||||
m_values = track->m_values;
|
||||
}
|
||||
|
||||
/// Set the value of a certain keyframe
|
||||
inline void setValue(size_t idx, const value_type &value) { m_values[idx] = value; }
|
||||
inline void setValue(size_t idx, const ValueType &value) { m_values[idx] = value; }
|
||||
|
||||
/// Return the value of a certain keyframe
|
||||
inline const value_type &getValue(size_t idx) const { return m_values[idx]; }
|
||||
inline const ValueType &getValue(size_t idx) const { return m_values[idx]; }
|
||||
|
||||
/// Reserve space for a certain number of entries
|
||||
inline void reserve(size_t count) { m_times.reserve(count); m_values.reserve(count); }
|
||||
|
||||
/// Append a value
|
||||
inline void append(Float time, const ValueType &value) {
|
||||
m_times.push_back(time);
|
||||
m_values.push_back(value);
|
||||
}
|
||||
|
||||
/// Clone this instance
|
||||
AbstractAnimationTrack *clone() const {
|
||||
return new AnimationTrack(this);
|
||||
}
|
||||
|
||||
/// Prepend a transformation to every entry of this track
|
||||
void prependTransformation(const ValueType &value) {
|
||||
for (size_t i=0; i<m_values.size(); ++i)
|
||||
m_values[i] = concatenateTransformations(m_values[i], value);
|
||||
}
|
||||
|
||||
/// Append a transformation to every entry of this track
|
||||
void appendTransformation(const ValueType &value) {
|
||||
for (size_t i=0; i<m_values.size(); ++i)
|
||||
m_values[i] = concatenateTransformations(value, m_values[i]);
|
||||
}
|
||||
|
||||
/// Serialize to a binary data stream
|
||||
inline void serialize(Stream *stream) const {
|
||||
|
@ -111,7 +148,7 @@ public:
|
|||
}
|
||||
|
||||
/// Evaluate the animation track at an arbitrary time value
|
||||
inline value_type eval(Float time) const {
|
||||
inline ValueType eval(Float time) const {
|
||||
SAssert(m_times.size() > 0);
|
||||
std::vector<Float>::const_iterator entry =
|
||||
std::lower_bound(m_times.begin(), m_times.end(), time);
|
||||
|
@ -126,19 +163,84 @@ public:
|
|||
}
|
||||
return lerp(idx0, idx1, t);
|
||||
}
|
||||
|
||||
private:
|
||||
struct SortPredicate {
|
||||
inline bool operator()(const std::pair<Float, ValueType> &p1,
|
||||
const std::pair<Float, ValueType> &p2) const {
|
||||
return p1.first < p2.first;
|
||||
}
|
||||
};
|
||||
|
||||
struct UniqueTimePredicate {
|
||||
inline bool operator()(const std::pair<Float, ValueType> &p1,
|
||||
const std::pair<Float, ValueType> &p2) const {
|
||||
return p1.first == p2.first;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Sort all animation tracks and remove
|
||||
* unnecessary data (for user-provided input)
|
||||
*
|
||||
* \return \c false if this animation track was deemed to be "trivial"
|
||||
* after the cleanup (for instance, it only contains (0,0,0) translation operations)
|
||||
*/
|
||||
bool sortAndSimplify() {
|
||||
SAssert(m_values.size() == m_times.size());
|
||||
if (m_values.size() == 0)
|
||||
return false;
|
||||
|
||||
std::vector< std::pair<Float, ValueType> > temp(m_values.size());
|
||||
for (size_t i=0; i<m_values.size(); ++i)
|
||||
temp[i] = std::make_pair(m_times[i], m_values[i]);
|
||||
std::sort(temp.begin(), temp.end(), SortPredicate());
|
||||
|
||||
m_times.clear(); m_values.clear();
|
||||
m_times.push_back(temp[0].first);
|
||||
m_values.push_back(temp[0].second);
|
||||
|
||||
for (size_t i=1; i<temp.size(); ++i) {
|
||||
Float time = temp[i].first;
|
||||
const ValueType &value = temp[i].second;
|
||||
|
||||
if (m_times.back() == time)
|
||||
SLog(EError, "Duplicate time value in animated transformation!");
|
||||
|
||||
/* Ignore irrelevant keys */
|
||||
if (i+1 < temp.size() && value == temp[i+1].second &&
|
||||
value == m_values.back())
|
||||
continue;
|
||||
else if (i+1 == temp.size() && value == m_values.back())
|
||||
continue;
|
||||
|
||||
m_times.push_back(time);
|
||||
m_values.push_back(value);
|
||||
}
|
||||
|
||||
return !(m_values.size() == 0 || (m_values.size() == 1 && isNoOp(m_values[0])));
|
||||
}
|
||||
protected:
|
||||
/// Evaluate the animation track using linear interpolation
|
||||
inline value_type lerp(size_t idx0, size_t idx1, Float t) const;
|
||||
inline ValueType lerp(size_t idx0, size_t idx1, Float t) const;
|
||||
|
||||
inline void unserialize(Stream *stream, value_type &value) {
|
||||
value = stream->readElement<value_type>();
|
||||
/// Is this a "no-op" transformation?
|
||||
inline bool isNoOp(const ValueType &value) const;
|
||||
|
||||
/// Concatenate two transformations
|
||||
inline ValueType concatenateTransformations(
|
||||
const ValueType &value1, const ValueType &value2) const;
|
||||
|
||||
inline void unserialize(Stream *stream, ValueType &value) {
|
||||
value = stream->readElement<ValueType>();
|
||||
}
|
||||
|
||||
inline void serialize(Stream *stream, const value_type &value) const {
|
||||
stream->writeElement<value_type>(value);
|
||||
inline void serialize(Stream *stream, const ValueType &value) const {
|
||||
stream->writeElement<ValueType>(value);
|
||||
}
|
||||
private:
|
||||
std::vector<value_type> m_values;
|
||||
std::vector<ValueType> m_values;
|
||||
};
|
||||
|
||||
template<typename T> inline T AnimationTrack<T>::lerp(size_t idx0, size_t idx1, Float t) const {
|
||||
|
@ -150,6 +252,58 @@ template<> inline Quaternion AnimationTrack<Quaternion>::lerp(size_t idx0, size_
|
|||
return slerp(m_values[idx0], m_values[idx1], t);
|
||||
}
|
||||
|
||||
template<typename T> inline T AnimationTrack<T>::concatenateTransformations(
|
||||
const T &value1, const T &value2) const {
|
||||
return value1 * value2;
|
||||
}
|
||||
|
||||
template<> inline Vector AnimationTrack<Vector>::concatenateTransformations(
|
||||
const Vector &value1, const Vector &value2) const {
|
||||
if (m_type == ETranslationXYZ)
|
||||
return value1 + value2;
|
||||
else
|
||||
return Vector(value1.x * value2.x, value1.y * value2.y, value1.z * value2.z);
|
||||
}
|
||||
|
||||
template<> inline Point AnimationTrack<Point>::concatenateTransformations(
|
||||
const Point &value1, const Point &value2) const {
|
||||
return value1 + value2;
|
||||
}
|
||||
|
||||
template<> inline Float AnimationTrack<Float>::concatenateTransformations(
|
||||
const Float &value1, const Float &value2) const {
|
||||
if (m_type == ETranslationX || m_type == ETranslationY || m_type == ETranslationZ)
|
||||
return value1 + value2;
|
||||
else
|
||||
return value1 * value2;
|
||||
}
|
||||
|
||||
template<typename T> inline bool AnimationTrack<T>::isNoOp(const ValueType &value) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> inline bool AnimationTrack<Float>::isNoOp(const Float &value) const {
|
||||
if ((m_type == ETranslationX || m_type == ETranslationY || m_type == ETranslationZ) && value == 0)
|
||||
return true;
|
||||
else if ((m_type == ERotationX || m_type == ERotationY || m_type == ERotationZ) && value == 0)
|
||||
return true;
|
||||
else if ((m_type == EScaleX || m_type == EScaleY || m_type == EScaleZ) && value == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> inline bool AnimationTrack<Vector>::isNoOp(const Vector &value) const {
|
||||
if (m_type == ETranslationXYZ && value.isZero())
|
||||
return true;
|
||||
else if (m_type == EScaleXYZ && (value.x == 1 && value.y == 1 && value.z == 1))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> inline bool AnimationTrack<Quaternion>::isNoOp(const Quaternion &value) const {
|
||||
return value.isIdentity();
|
||||
}
|
||||
|
||||
template<> inline void AnimationTrack<Point>::unserialize(Stream *stream, Point &value) {
|
||||
value = Point(stream);
|
||||
}
|
||||
|
@ -178,10 +332,10 @@ template<> inline void AnimationTrack<Quaternion>::serialize(Stream *stream, con
|
|||
* \brief Animated transformation with an underlying keyframe representation
|
||||
* \ingroup librender
|
||||
*/
|
||||
class MTS_EXPORT_RENDER AnimatedTransform : public Object {
|
||||
protected:
|
||||
class MTS_EXPORT_CORE AnimatedTransform : public Object {
|
||||
private:
|
||||
/// Internal functor used by \ref eval() and \ref SimpleCache
|
||||
struct MTS_EXPORT_RENDER TransformFunctor {
|
||||
struct MTS_EXPORT_CORE TransformFunctor {
|
||||
public:
|
||||
inline TransformFunctor(const std::vector<AbstractAnimationTrack *> &tracks)
|
||||
: m_tracks(tracks) {}
|
||||
|
@ -204,15 +358,40 @@ public:
|
|||
/// Unserialized an animated transformation from a binary data stream
|
||||
AnimatedTransform(Stream *stream);
|
||||
|
||||
/// Copy constructor
|
||||
AnimatedTransform(const AnimatedTransform *trafo);
|
||||
|
||||
/// Return the number of associated animation tracks
|
||||
inline size_t getTrackCount() const { return m_tracks.size(); }
|
||||
|
||||
/// Find a track of the given type
|
||||
AbstractAnimationTrack *findTrack(AbstractAnimationTrack::EType type);
|
||||
|
||||
/// Find a track of the given type
|
||||
const AbstractAnimationTrack *findTrack(AbstractAnimationTrack::EType type) const;
|
||||
|
||||
/// Look up one of the tracks by index
|
||||
inline AbstractAnimationTrack *getTrack(size_t idx) { return m_tracks[idx]; }
|
||||
|
||||
/// Look up one of the tracks by index (const version)
|
||||
inline const AbstractAnimationTrack *getTrack(size_t idx) const { return m_tracks[idx]; }
|
||||
|
||||
/// Return the used keyframes as a set
|
||||
void collectKeyframes(std::set<Float> &result) const;
|
||||
|
||||
/// Append an animation track
|
||||
void addTrack(AbstractAnimationTrack *track);
|
||||
|
||||
/**
|
||||
* \brief Convenience function, which appends a linear transformation to the track
|
||||
*
|
||||
* Internally, a polar decomposition is used to split the transformation into scale,
|
||||
* translation, and rotation, which are all separately interpolated.
|
||||
*
|
||||
* \remark Remember to run \ref sortAndSimplify() after adding all transformations.
|
||||
*/
|
||||
void appendTransform(Float time, const Transform &trafo);
|
||||
|
||||
/**
|
||||
* \brief Compute the transformation for the specified time value
|
||||
*
|
||||
|
@ -221,7 +400,7 @@ public:
|
|||
* to this function.
|
||||
*/
|
||||
inline const Transform &eval(Float t) const {
|
||||
if (m_tracks.size() == 0)
|
||||
if (EXPECT_TAKEN(m_tracks.size() == 0))
|
||||
return m_transform;
|
||||
else
|
||||
return m_cache.get(TransformFunctor(m_tracks), t);
|
||||
|
@ -230,6 +409,12 @@ public:
|
|||
/// Is the animation static?
|
||||
inline bool isStatic() const { return m_tracks.size() == 0; }
|
||||
|
||||
/**
|
||||
* \brief Sort all animation tracks and remove unnecessary
|
||||
* data (for user-provided input)
|
||||
*/
|
||||
void sortAndSimplify();
|
||||
|
||||
/// Transform a point by an affine / non-projective matrix
|
||||
inline Point transformAffine(Float t, const Point &p) const {
|
||||
return eval(t).transformAffine(p);
|
||||
|
@ -290,6 +475,9 @@ public:
|
|||
eval(t).operator()(r, dest);
|
||||
}
|
||||
|
||||
/// Prepend a scale transformation to the transform (this is often useful)
|
||||
void prependScale(const Vector &scale);
|
||||
|
||||
/// Serialize to a binary data stream
|
||||
void serialize(Stream *stream) const;
|
||||
|
||||
|
@ -317,4 +505,4 @@ private:
|
|||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __MITSUBA_RENDER_TRACK_H_ */
|
||||
#endif /* __MITSUBA_CORE_TRACK_H_ */
|
|
@ -393,6 +393,16 @@ public:
|
|||
m_invTransform.serialize(stream);
|
||||
}
|
||||
|
||||
/// Equality comparison operator
|
||||
inline bool operator==(const Transform &trafo) const {
|
||||
return m_transform == trafo.m_transform;
|
||||
}
|
||||
|
||||
/// Inequality comparison operator
|
||||
inline bool operator!=(const Transform &trafo) const {
|
||||
return m_transform != trafo.m_transform;
|
||||
}
|
||||
|
||||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
private:
|
||||
|
|
|
@ -58,9 +58,10 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
*/
|
||||
AABB getClippedAABB(const Point *positions, const AABB &aabb) const;
|
||||
|
||||
/// Uniformly sample a point on the triangle and return its normal
|
||||
/// Uniformly sample a point on the triangle and return its normal and UV coordinates
|
||||
Point sample(const Point *positions, const Normal *normals,
|
||||
Normal &n, const Point2 &seed) const;
|
||||
const Point2 *texCoords, Normal &n, Point2 &uv,
|
||||
const Point2 &seed) const;
|
||||
|
||||
/// Calculate the surface area of this triangle
|
||||
Float surfaceArea(const Point *positions) const;
|
||||
|
|
|
@ -58,7 +58,7 @@ extern MTS_EXPORT_CORE std::string formatString(const char *pFmt, ...);
|
|||
extern MTS_EXPORT_CORE std::string timeString(Float time, bool precise = false);
|
||||
|
||||
/// Turn a memory size into a human-readable string
|
||||
extern MTS_EXPORT_CORE std::string memString(size_t size);
|
||||
extern MTS_EXPORT_CORE std::string memString(size_t size, bool precise = false);
|
||||
|
||||
/// Return a string representation of a list of objects
|
||||
template<class Iterator> std::string containerToString(const Iterator &start, const Iterator &end) {
|
||||
|
@ -110,6 +110,9 @@ extern MTS_EXPORT_CORE int getCoreCount();
|
|||
/// Return the host name of this machine
|
||||
extern MTS_EXPORT_CORE std::string getHostName();
|
||||
|
||||
/// Return the process private memory usage in bytes
|
||||
extern MTS_EXPORT_CORE size_t getPrivateMemoryUsage();
|
||||
|
||||
/// Return the fully qualified domain name of this machine
|
||||
extern MTS_EXPORT_CORE std::string getFQDN();
|
||||
|
||||
|
@ -172,6 +175,34 @@ static FINLINE uint64_t rdtsc(void) {
|
|||
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
return ((uint64_t) lo)| (((uint64_t) hi) << 32);
|
||||
}
|
||||
#elif defined(__ARMEL__)
|
||||
static FINLINE uint64_t rdtsc(void) {
|
||||
// Code from gperftoos:
|
||||
// https://code.google.com/p/gperftools/source/browse/trunk/src/base/cycleclock.h
|
||||
uint32_t pmccntr;
|
||||
uint32_t pmuseren;
|
||||
uint32_t pmcntenset;
|
||||
// Read the user mode perf monitor counter access permissions.
|
||||
asm volatile ("mrc p15, 0, %0, c9, c14, 0" : "=r" (pmuseren));
|
||||
if (EXPECT_TAKEN(pmuseren & 1)) { // Allows reading perfmon counters for user mode code.
|
||||
asm volatile ("mrc p15, 0, %0, c9, c12, 1" : "=r" (pmcntenset));
|
||||
if (EXPECT_TAKEN(pmcntenset & 0x80000000ul)) { // Is it counting?
|
||||
asm volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r" (pmccntr));
|
||||
// The counter is set up to count every 64th cycle
|
||||
return static_cast<uint64_t>(pmccntr) * 64; // Should optimize to << 6
|
||||
}
|
||||
}
|
||||
// Soft-failover, assuming 1.5GHz CPUs
|
||||
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) && defined(_POSIX_CPUTIME)
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
|
||||
return static_cast<uint64_t>((ts.tv_sec + ts.tv_nsec * 1e-9) * 1.5e9);
|
||||
#else
|
||||
timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return static_cast<uint64_t>((tv.tv_sec + tv.tv_usec * 1e-6) * 1.5e9);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#elif defined(__MSVC__)
|
||||
static FINLINE __int64 rdtsc(void) {
|
||||
|
@ -340,162 +371,6 @@ extern MTS_EXPORT_CORE bool solveQuadratic(Float a, Float b,
|
|||
extern MTS_EXPORT_CORE bool solveQuadraticDouble(double a, double b,
|
||||
double c, double &x0, double &x1);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 1D function
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* \param data
|
||||
* Floating point array containing \c size regularly spaced evaluations
|
||||
* in the range [\c min,\c max] of the function to be approximated.
|
||||
* \param min
|
||||
* Position of the first knot
|
||||
* \param max
|
||||
* Position of the last knot
|
||||
* \param size
|
||||
* Denotes the size of the \c data array
|
||||
* \return
|
||||
* The interpolated value or zero when \c x lies outside of [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic1D(Float x, const Float *data,
|
||||
Float min, Float max, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 1D function
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Floating point array containing \c size irregularly spaced values
|
||||
* denoting positions the where the function to be interpolated was evaluated.
|
||||
* They must be provided in \a increasing order.
|
||||
* \param data
|
||||
* Floating point array containing interpolant values matched to
|
||||
* the entries of \c nodes.
|
||||
* \param size
|
||||
* Denotes the size of the \c data array
|
||||
* \return
|
||||
* The interpolated value or zero when \c x lies outside of \a [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT Float interpCubic1DIrregular(Float x, const Float *nodes,
|
||||
const Float *data, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* patch.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic2D(const Point2 &p, const Float *data,
|
||||
const Point2 &min, const Point2 &max, const Size2 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* When the underlying function is sampled on a regular grid, \ref interpCubic2D()
|
||||
* should be preferred, since data lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing irregularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic2DIrregular(const Point2 &p, const Float **nodes,
|
||||
const Float *data, const Size2 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point of the interpolant
|
||||
* \param data
|
||||
* A 3D floating point array of <tt>size.x*size.y*size.z</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic3D(const Point3 &p, const Float *data,
|
||||
const Point3 &min, const Point3 &max, const Size3 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
* When the underlying function is sampled on a regular grid, \ref interpCubic3D()
|
||||
* should be preferred, since data lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing irregularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic3DIrregular(const Point3 &p, const Float **nodes,
|
||||
const Float *data, const Size3 &size);
|
||||
|
||||
//// Convert radians to degrees
|
||||
inline Float radToDeg(Float value) { return value * (180.0f / M_PI); }
|
||||
|
||||
|
@ -663,22 +538,99 @@ inline Float fresnelDielectricExt(Float cosThetaI, Float eta) { Float cosThetaT;
|
|||
return fresnelDielectricExt(cosThetaI, cosThetaT, eta); }
|
||||
|
||||
/**
|
||||
* \brief Calculates the unpolarized fresnel reflection coefficient
|
||||
* at a planar interface between vacuum and a conductor.
|
||||
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||
* at a planar interface having a complex-valued relative index of
|
||||
* refraction (approximate scalar version)
|
||||
*
|
||||
* The implementation of this function relies on a simplified expression
|
||||
* that becomes increasingly accurate as k grows.
|
||||
*
|
||||
* The name of this function is a slight misnomer, since it supports
|
||||
* the general case of a complex-valued relative index of refraction
|
||||
* (rather than being restricted to conductors)
|
||||
*
|
||||
* \param cosThetaI
|
||||
* Cosine of the angle between the normal and the incident ray
|
||||
* \param eta
|
||||
* Real refractive index (wavelength-dependent)
|
||||
* Relative refractive index (real component)
|
||||
* \param k
|
||||
* Imaginary refractive index (wavelength-dependent)
|
||||
* Relative refractive index (imaginary component)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosThetaI,
|
||||
extern MTS_EXPORT_CORE Float fresnelConductorApprox(Float cosThetaI,
|
||||
Float eta, Float k);
|
||||
|
||||
/**
|
||||
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||
* at a planar interface having a complex-valued relative index of
|
||||
* refraction (approximate vectorized version)
|
||||
*
|
||||
* The implementation of this function relies on a simplified expression
|
||||
* that becomes increasingly accurate as k grows.
|
||||
*
|
||||
* The name of this function is a slight misnomer, since it supports
|
||||
* the general case of a complex-valued relative index of refraction
|
||||
* (rather than being restricted to conductors)
|
||||
*
|
||||
* \param cosThetaI
|
||||
* Cosine of the angle between the normal and the incident ray
|
||||
* \param eta
|
||||
* Relative refractive index (real component)
|
||||
* \param k
|
||||
* Relative refractive index (imaginary component)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Spectrum fresnelConductorApprox(Float cosThetaI,
|
||||
const Spectrum &eta, const Spectrum &k);
|
||||
|
||||
/**
|
||||
* \brief Calculates the diffuse unpolarized fresnel reflectance of
|
||||
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||
* at a planar interface having a complex-valued relative index of
|
||||
* refraction (accurate scalar version)
|
||||
*
|
||||
* The implementation of this function computes the exact unpolarized
|
||||
* Fresnel reflectance for a complex index of refraction change.
|
||||
*
|
||||
* The name of this function is a slight misnomer, since it supports
|
||||
* the general case of a complex-valued relative index of refraction
|
||||
* (rather than being restricted to conductors)
|
||||
*
|
||||
* \param cosThetaI
|
||||
* Cosine of the angle between the normal and the incident ray
|
||||
* \param eta
|
||||
* Relative refractive index (real component)
|
||||
* \param k
|
||||
* Relative refractive index (imaginary component)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float fresnelConductorExact(Float cosThetaI,
|
||||
Float eta, Float k);
|
||||
|
||||
/**
|
||||
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||
* at a planar interface having a complex-valued relative index of
|
||||
* refraction (accurate vectorized version)
|
||||
*
|
||||
* The implementation of this function computes the exact unpolarized
|
||||
* Fresnel reflectance for a complex index of refraction change.
|
||||
*
|
||||
* The name of this function is a slight misnomer, since it supports
|
||||
* the general case of a complex-valued relative index of refraction
|
||||
* (rather than being restricted to conductors)
|
||||
*
|
||||
* \param cosThetaI
|
||||
* Cosine of the angle between the normal and the incident ray
|
||||
* \param eta
|
||||
* Relative refractive index (real component)
|
||||
* \param k
|
||||
* Relative refractive index (imaginary component)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Spectrum fresnelConductorExact(Float cosThetaI,
|
||||
const Spectrum &eta, const Spectrum &k);
|
||||
|
||||
/**
|
||||
* \brief Calculates the diffuse unpolarized Fresnel reflectance of
|
||||
* a dielectric material (sometimes referred to as "Fdr").
|
||||
*
|
||||
* This value quantifies what fraction of diffuse incident illumination
|
||||
|
|
|
@ -189,6 +189,13 @@ template <typename T> inline TVector1<T> normalize(const TVector1<T> &v) {
|
|||
return v / v.length();
|
||||
}
|
||||
|
||||
template <typename T> inline TVector1<T> normalizeStrict(const TVector1<T> &v, const char *errMsg) {
|
||||
Float length = v.length();
|
||||
if (length == 0)
|
||||
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||
return v / length;
|
||||
}
|
||||
|
||||
template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
|
@ -207,6 +214,27 @@ template <> inline TVector1<int> &TVector1<int>::operator/=(int s) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
// Helper structures to define "length" as a floating point value
|
||||
|
||||
template <typename T, bool IsInteger = false> struct VectorLength {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T> struct VectorLength<T, true> {
|
||||
typedef Float type;
|
||||
};
|
||||
|
||||
template <> struct VectorLength<uint64_t, true> {
|
||||
typedef double type;
|
||||
};
|
||||
|
||||
template <> struct VectorLength<int64_t, true> {
|
||||
typedef double type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \headerfile mitsuba/core/vector.h mitsuba/mitsuba.h
|
||||
* \brief Parameterizable two-dimensional vector data structure
|
||||
|
@ -215,6 +243,7 @@ template <> inline TVector1<int> &TVector1<int>::operator/=(int s) {
|
|||
template <typename T> struct TVector2 {
|
||||
typedef T Scalar;
|
||||
typedef TPoint2<T> PointType;
|
||||
typedef typename detail::VectorLength<T, std::numeric_limits<T>::is_integer>::type LengthType;
|
||||
|
||||
T x, y;
|
||||
|
||||
|
@ -331,8 +360,8 @@ template <typename T> struct TVector2 {
|
|||
}
|
||||
|
||||
/// Return the 2-norm of this vector
|
||||
T length() const {
|
||||
return std::sqrt(lengthSquared());
|
||||
LengthType length() const {
|
||||
return (LengthType) std::sqrt((LengthType) lengthSquared());
|
||||
}
|
||||
|
||||
/// Return whether or not this vector is identically zero
|
||||
|
@ -376,10 +405,21 @@ template <typename T> inline T absDot(const TVector2<T> &v1, const TVector2<T> &
|
|||
return std::abs(dot(v1, v2));
|
||||
}
|
||||
|
||||
template <typename T> inline T det(const TVector2<T> &v1, const TVector2<T> &v2) {
|
||||
return v1.x * v2.y - v1.y * v2.x;
|
||||
}
|
||||
|
||||
template <typename T> inline TVector2<T> normalize(const TVector2<T> &v) {
|
||||
return v / v.length();
|
||||
}
|
||||
|
||||
template <typename T> inline TVector2<T> normalizeStrict(const TVector2<T> &v, const char *errMsg) {
|
||||
Float length = v.length();
|
||||
if (length == 0)
|
||||
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||
return v / length;
|
||||
}
|
||||
|
||||
template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
|
@ -407,6 +447,7 @@ template <> inline TVector2<int> &TVector2<int>::operator/=(int s) {
|
|||
template <typename T> struct TVector3 {
|
||||
typedef T Scalar;
|
||||
typedef TPoint3<T> PointType;
|
||||
typedef typename detail::VectorLength<T, std::numeric_limits<T>::is_integer>::type LengthType;
|
||||
|
||||
T x, y, z;
|
||||
|
||||
|
@ -524,8 +565,8 @@ template <typename T> struct TVector3 {
|
|||
}
|
||||
|
||||
/// Return the 2-norm of this vector
|
||||
T length() const {
|
||||
return std::sqrt(lengthSquared());
|
||||
LengthType length() const {
|
||||
return (LengthType) std::sqrt((LengthType) lengthSquared());
|
||||
}
|
||||
|
||||
/// Return whether or not this vector is identically zero
|
||||
|
@ -582,6 +623,13 @@ template <typename T> inline TVector3<T> normalize(const TVector3<T> &v) {
|
|||
return v / v.length();
|
||||
}
|
||||
|
||||
template <typename T> inline TVector3<T> normalizeStrict(const TVector3<T> &v, const char *errMsg) {
|
||||
Float length = v.length();
|
||||
if (length == 0)
|
||||
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||
return v / length;
|
||||
}
|
||||
|
||||
template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
|
@ -611,12 +659,12 @@ template <> inline TVector3<int> &TVector3<int>::operator/=(int s) {
|
|||
template <typename T> struct TVector4 {
|
||||
typedef T Scalar;
|
||||
typedef TPoint4<T> PointType;
|
||||
typedef typename detail::VectorLength<T, std::numeric_limits<T>::is_integer>::type LengthType;
|
||||
|
||||
T x, y, z, w;
|
||||
|
||||
/// Number of dimensions
|
||||
const static int dim = 3;
|
||||
|
||||
const static int dim = 4;
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
|
@ -730,8 +778,8 @@ template <typename T> struct TVector4 {
|
|||
}
|
||||
|
||||
/// Return the 2-norm of this vector
|
||||
T length() const {
|
||||
return std::sqrt(lengthSquared());
|
||||
LengthType length() const {
|
||||
return (LengthType) std::sqrt((LengthType) lengthSquared());
|
||||
}
|
||||
|
||||
/// Return whether or not this vector is identically zero
|
||||
|
@ -781,6 +829,13 @@ template <typename T> inline TVector4<T> normalize(const TVector4<T> &v) {
|
|||
return v / v.length();
|
||||
}
|
||||
|
||||
template <typename T> inline TVector4<T> normalizeStrict(const TVector4<T> &v, const char *errMsg) {
|
||||
Float length = v.length();
|
||||
if (length == 0)
|
||||
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||
return v / length;
|
||||
}
|
||||
|
||||
template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
|
|
|
@ -26,13 +26,13 @@ MTS_NAMESPACE_BEGIN
|
|||
* \brief Current release of Mitsuba
|
||||
* \ingroup libcore
|
||||
*/
|
||||
#define MTS_VERSION "0.4.1"
|
||||
#define MTS_VERSION "0.4.4"
|
||||
|
||||
/**
|
||||
* \brief Year of the current release
|
||||
* \ingroup libcore
|
||||
*/
|
||||
#define MTS_YEAR "2012"
|
||||
#define MTS_YEAR "2013"
|
||||
|
||||
/**
|
||||
* \brief A simple data structure for representing and
|
||||
|
|
|
@ -114,6 +114,12 @@ public:
|
|||
/// Warp a uniformly distributed square sample to a 2D tent distribution
|
||||
static Point2 squareToTent(const Point2 &sample);
|
||||
|
||||
/**
|
||||
* \brief Warp a uniformly distributed sample on [0, 1] to a nonuniform
|
||||
* tent distribution with nodes <tt>{a, b, c}</tt>
|
||||
*/
|
||||
static Float intervalToNonuniformTent(Float a, Float b, Float c, Float sample);
|
||||
|
||||
//! @}
|
||||
// =============================================================
|
||||
};
|
||||
|
|
|
@ -76,12 +76,22 @@ public:
|
|||
/// Allocate memory for a certain font
|
||||
Font(EFont font);
|
||||
|
||||
/// Draw text to the specified bitmap
|
||||
void drawText(Bitmap *dest, Point2i pos, const std::string &text) const;
|
||||
|
||||
/// Compute the size covered by the given string when rendered using this font
|
||||
Vector2i getSize(const std::string &text) const;
|
||||
|
||||
/// Upload the font to the GPU
|
||||
void init(Renderer *renderer);
|
||||
|
||||
/// Free the GPU memory
|
||||
void cleanup();
|
||||
|
||||
/// Convert the underlying bitmap to a different pixel format
|
||||
void convert(Bitmap::EPixelFormat pixelFormat,
|
||||
Bitmap::EComponentFormat componentFormat, Float gamma);
|
||||
|
||||
/// Return the name of this font
|
||||
inline const std::string &getName() const { return m_name; }
|
||||
|
||||
|
|
|
@ -326,11 +326,14 @@ protected:
|
|||
* number of GPU pipeline flushes. Draw transparent objects last.
|
||||
*/
|
||||
struct MaterialOrder {
|
||||
inline bool operator()(
|
||||
const Renderer::TransformedGPUGeometry &g1,
|
||||
const Renderer::TransformedGPUGeometry &g2) const {
|
||||
const Shader *shader1 = g1.first->getShader();
|
||||
const Shader *shader2 = g2.first->getShader();
|
||||
const std::vector<Renderer::TransformedGPUGeometry> &geo;
|
||||
|
||||
MaterialOrder(const std::vector<Renderer::TransformedGPUGeometry> &geo)
|
||||
: geo(geo) { }
|
||||
|
||||
inline bool operator()(size_t idx1, size_t idx2) const {
|
||||
const Shader *shader1 = geo[idx1].first->getShader();
|
||||
const Shader *shader2 = geo[idx2].first->getShader();
|
||||
|
||||
if (shader1 && (shader1->getFlags() & Shader::ETransparent))
|
||||
shader1 = NULL;
|
||||
|
@ -340,6 +343,19 @@ protected:
|
|||
return shader1 < shader2;
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper data structure to keep track of shapes that are undergoing keyframe animations
|
||||
struct AnimatedGeometryRecord {
|
||||
const AnimatedTransform *trafo;
|
||||
ssize_t geometryIndex;
|
||||
ssize_t opaqueGeometryIndex;
|
||||
|
||||
AnimatedGeometryRecord(const AnimatedTransform *trafo,
|
||||
ssize_t geometryIndex, ssize_t opaqueGeometryIndex) :
|
||||
trafo(trafo), geometryIndex(geometryIndex),
|
||||
opaqueGeometryIndex(opaqueGeometryIndex) { }
|
||||
};
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
private:
|
||||
ref<Renderer> m_renderer;
|
||||
|
@ -348,6 +364,7 @@ private:
|
|||
/* On-GPU geometry references */
|
||||
std::vector<Renderer::TransformedGPUGeometry> m_geometry;
|
||||
std::vector<Renderer::TransformedGPUGeometry> m_opaqueGeometry;
|
||||
std::vector<AnimatedGeometryRecord> m_animatedGeometry;
|
||||
|
||||
/* Shader & dependency management */
|
||||
std::map<std::string, VPLConfiguration> m_configurations;
|
||||
|
|
|
@ -45,7 +45,7 @@ using std::endl;
|
|||
#include <mitsuba/core/constants.h>
|
||||
#include <mitsuba/core/fwd.h>
|
||||
#include <mitsuba/render/fwd.h>
|
||||
#include <mitsuba/core/stl.h>
|
||||
#include <mitsuba/core/math.h>
|
||||
#include <mitsuba/core/object.h>
|
||||
#include <mitsuba/core/ref.h>
|
||||
#include <mitsuba/core/tls.h>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define __MITSUBA_RENDER_EMITTER_H_
|
||||
|
||||
#include <mitsuba/render/common.h>
|
||||
#include <mitsuba/render/track.h>
|
||||
#include <mitsuba/core/track.h>
|
||||
#include <mitsuba/core/properties.h>
|
||||
#include <mitsuba/core/cobject.h>
|
||||
#include <mitsuba/render/shader.h>
|
||||
|
@ -425,7 +425,7 @@ protected:
|
|||
/// Virtual destructor
|
||||
virtual ~AbstractEmitter();
|
||||
protected:
|
||||
ref<AnimatedTransform> m_worldTransform;
|
||||
ref<const AnimatedTransform> m_worldTransform;
|
||||
ref<Medium> m_medium;
|
||||
Shape *m_shape;
|
||||
uint32_t m_type;
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
virtual void setDestinationFile(const fs::path &filename, uint32_t blockSize) = 0;
|
||||
|
||||
/// Develop the film and write the result to the previously specified filename
|
||||
virtual void develop() = 0;
|
||||
virtual void develop(const Scene *scene, Float renderTime) = 0;
|
||||
|
||||
/**
|
||||
* \brief Develop the contents of a subregion of the film and store
|
||||
|
@ -88,6 +88,9 @@ public:
|
|||
*/
|
||||
inline bool hasHighQualityEdges() const { return m_highQualityEdges; }
|
||||
|
||||
/// Return whether or not this film records the alpha channel
|
||||
virtual bool hasAlpha() const = 0;
|
||||
|
||||
/// Return the image reconstruction filter
|
||||
inline ReconstructionFilter *getReconstructionFilter() { return m_filter.get(); }
|
||||
|
||||
|
|
|
@ -22,13 +22,6 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
class AbstractAnimationTrack;
|
||||
template <typename T> class AnimationTrack;
|
||||
typedef AnimationTrack<Float> FloatTrack;
|
||||
typedef AnimationTrack<Quaternion> QuatTrack;
|
||||
typedef AnimationTrack<Vector> VectorTrack;
|
||||
typedef AnimationTrack<Point> PointTrack;
|
||||
class AnimatedTransform;
|
||||
class BlockedImageProcess;
|
||||
class BlockedRenderProcess;
|
||||
class BlockListener;
|
||||
|
|
|
@ -1321,7 +1321,9 @@ protected:
|
|||
return a.axis < b.axis;
|
||||
if (a.pos != b.pos)
|
||||
return a.pos < b.pos;
|
||||
if (a.type != b.type)
|
||||
return a.type < b.type;
|
||||
return a.index < b.index;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -220,6 +220,7 @@ public:
|
|||
medium = _medium;
|
||||
depth = 1;
|
||||
extra = 0;
|
||||
alpha = 1;
|
||||
}
|
||||
|
||||
/// Initialize the query record for a recursive query
|
||||
|
@ -457,6 +458,7 @@ protected:
|
|||
int m_maxDepth;
|
||||
int m_rrDepth;
|
||||
bool m_strictNormals;
|
||||
bool m_hideEmitters;
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
|
|
@ -60,11 +60,11 @@ public:
|
|||
/// The medium's scattering coefficient at \ref p
|
||||
Spectrum sigmaS;
|
||||
|
||||
/// Records the probability of sampling a medium interaction at p
|
||||
/// Records the probability density of sampling a medium interaction at p
|
||||
Float pdfSuccess;
|
||||
|
||||
/**
|
||||
* \brief Records the probability of sampling a medium
|
||||
* \brief Records the probability density of sampling a medium
|
||||
* interaction in the reverse direction
|
||||
*
|
||||
* This is essentially the density of obtained by calling \ref sampleDistance,
|
||||
|
|
|
@ -179,6 +179,9 @@ public:
|
|||
* \param depth
|
||||
* Depth of the interaction in path space (with 1
|
||||
* corresponding to the first bounce)
|
||||
* \param nullInteractions
|
||||
* Specifies how many of these interactions were of type BSDF::ENull
|
||||
* (i.e. index-matched medium transitions)
|
||||
* \param delta
|
||||
* Denotes if the previous scattering event was a degenerate
|
||||
* specular reflection or refraction.
|
||||
|
@ -192,8 +195,8 @@ public:
|
|||
* all preceding interactions except for the current surface
|
||||
* interaction.
|
||||
*/
|
||||
virtual void handleSurfaceInteraction(int depth, bool delta,
|
||||
const Intersection &its, const Medium *medium,
|
||||
virtual void handleSurfaceInteraction(int depth, int nullInteractions,
|
||||
bool delta, const Intersection &its, const Medium *medium,
|
||||
const Spectrum &weight);
|
||||
|
||||
/**
|
||||
|
@ -205,6 +208,9 @@ public:
|
|||
* \param depth
|
||||
* Depth of the interaction in path space (with 1
|
||||
* corresponding to the first bounce)
|
||||
* \param nullInteractions
|
||||
* Specifies how many of these interactions were of type BSDF::ENull
|
||||
* (i.e. index-matched medium transitions)
|
||||
* \param delta
|
||||
* Denotes if the previous scattering event was a degenerate
|
||||
* specular reflection or refraction.
|
||||
|
@ -217,8 +223,8 @@ public:
|
|||
* all preceding interactions except for the current medium
|
||||
* interaction.
|
||||
*/
|
||||
virtual void handleMediumInteraction(int depth, bool delta,
|
||||
const MediumSamplingRecord &mRec, const Medium *medium,
|
||||
virtual void handleMediumInteraction(int depth, int nullInteractions,
|
||||
bool delta, const MediumSamplingRecord &mRec, const Medium *medium,
|
||||
const Vector &wi, const Spectrum &weight);
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
|
|
@ -101,12 +101,22 @@ inline bool RadianceQueryRecord::rayIntersect(const RayDifferential &ray) {
|
|||
if (type & EIntersection) {
|
||||
scene->rayIntersect(ray, its);
|
||||
if (type & EOpacity) {
|
||||
if (its.isValid())
|
||||
int unused = INT_MAX;
|
||||
|
||||
if (its.isValid()) {
|
||||
if (EXPECT_TAKEN(!its.isMediumTransition()))
|
||||
alpha = 1.0f;
|
||||
else if (medium == NULL)
|
||||
alpha = 0.0f;
|
||||
else
|
||||
alpha = 1-medium->evalTransmittance(ray).average();
|
||||
alpha = 1-scene->evalTransmittance(its.p, true,
|
||||
ray(scene->getBSphere().radius*2), false,
|
||||
ray.time, its.getTargetMedium(ray.d), unused).average();
|
||||
} else if (medium) {
|
||||
alpha = 1-scene->evalTransmittance(ray.o, false,
|
||||
ray(scene->getBSphere().radius*2), false,
|
||||
ray.time, medium, unused).average();
|
||||
} else {
|
||||
alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
if (type & EDistance)
|
||||
dist = its.t;
|
||||
|
@ -131,7 +141,7 @@ inline DirectionSamplingRecord::DirectionSamplingRecord(const Intersection &its,
|
|||
|
||||
inline DirectSamplingRecord::DirectSamplingRecord(const Intersection &refIts)
|
||||
: PositionSamplingRecord(refIts.time), ref(refIts.p), refN(0.0f) {
|
||||
if ((refIts.shape->getBSDF()->getType() & BSDF::ETransmission) == 0)
|
||||
if ((refIts.shape->getBSDF()->getType() & (BSDF::ETransmission | BSDF::EBackSide)) == 0)
|
||||
refN = refIts.shFrame.n;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
bool interactive = false);
|
||||
|
||||
/// Write out the current (partially rendered) image
|
||||
inline void flush() { m_scene->flush(); }
|
||||
inline void flush() { m_scene->flush(m_queue, this); }
|
||||
|
||||
/// Cancel a running render job
|
||||
inline void cancel() { m_scene->cancel(); }
|
||||
|
|
|
@ -76,6 +76,9 @@ public:
|
|||
/// Remove a (finished) render job from the queue
|
||||
void removeJob(RenderJob *thr, bool wasCancelled);
|
||||
|
||||
/// Return the amount of time spent rendering the given job (in seconds)
|
||||
Float getRenderTime(const RenderJob *job) const;
|
||||
|
||||
/// Register a render listener
|
||||
void registerListener(RenderListener *listener);
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
* Given a split on axis \a axis that produces children having extents
|
||||
* \a leftWidth and \a rightWidth along \a axis, compute the probability
|
||||
* of traversing the left and right child during a typical query
|
||||
* operation.
|
||||
* operation. In the case of the surface area heuristic, this is simply
|
||||
* the ratio of surface areas.
|
||||
*/
|
||||
inline std::pair<Float, Float> operator()(int axis, Float leftWidth, Float rightWidth) const {
|
||||
return std::pair<Float, Float>(
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2012 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License Version 3
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Mitsuba is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(__SAH_KDTREE4_H)
|
||||
#define __SAH_KDTREE4_H
|
||||
|
||||
#include <mitsuba/render/sahkdtree3.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
typedef TAABB<Point4> AABB4;
|
||||
|
||||
/**
|
||||
* \brief Implements the four-dimensional surface area heuristic for use
|
||||
* by the \ref GenericKDTree construction algorithm.
|
||||
*/
|
||||
class SurfaceAreaHeuristic4 {
|
||||
public:
|
||||
/**
|
||||
* \brief Initialize the surface area heuristic with the bounds of
|
||||
* a parent node
|
||||
*
|
||||
* Precomputes some information so that traversal probabilities
|
||||
* of potential split planes can be evaluated efficiently
|
||||
*/
|
||||
inline SurfaceAreaHeuristic4(const AABB4 &aabb) : m_aabb(aabb) {
|
||||
const Vector4 extents(aabb.getExtents());
|
||||
const Float temp = 1.0f / (extents.x * extents.y
|
||||
+ extents.y*extents.z + extents.x*extents.z);
|
||||
|
||||
m_temp0 = Vector4(
|
||||
extents.y * extents.z * temp,
|
||||
extents.x * extents.z * temp,
|
||||
extents.x * extents.y * temp,
|
||||
0.0f);
|
||||
|
||||
m_temp1 = Vector4(
|
||||
(extents.y + extents.z) * temp,
|
||||
(extents.x + extents.z) * temp,
|
||||
(extents.x + extents.y) * temp,
|
||||
1.0f / extents.w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a split on axis \a axis that produces children having extents
|
||||
* \a leftWidth and \a rightWidth along \a axis, compute the probability
|
||||
* of traversing the left and right child during a typical query
|
||||
* operation.
|
||||
*/
|
||||
inline std::pair<Float, Float> operator()(int axis, Float leftWidth, Float rightWidth) const {
|
||||
if (axis == 3 && m_temp1.w == std::numeric_limits<Float>::infinity()) {
|
||||
return std::pair<Float, Float>(
|
||||
std::numeric_limits<Float>::infinity(),
|
||||
std::numeric_limits<Float>::infinity()
|
||||
);
|
||||
}
|
||||
|
||||
return std::pair<Float, Float>(
|
||||
m_temp0[axis] + m_temp1[axis] * leftWidth,
|
||||
m_temp0[axis] + m_temp1[axis] * rightWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the underlying quantity used by the tree construction
|
||||
* heuristic. This is used to compute the final cost of a kd-tree.
|
||||
*/
|
||||
inline static Float getQuantity(const AABB4 &aabb) {
|
||||
const Vector4 extents(aabb.getExtents());
|
||||
Float result = 2 * (extents[0] * extents[1] + extents[1] * extents[2]
|
||||
+ extents[2] * extents[0]);
|
||||
if (extents[3] != 0)
|
||||
result *= extents[3];
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
Vector4 m_temp0, m_temp1;
|
||||
AABB4 m_aabb;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class specializes \ref GenericKDTree to a four-dimensional
|
||||
* tree to be used for spacetime ray tracing. One additional function call
|
||||
* must be implemented by subclasses:
|
||||
*
|
||||
* /// Check whether a primitive is intersected by the given ray.
|
||||
* /// Some temporary space is supplied, which can be used to cache
|
||||
* /// information about the intersection
|
||||
* bool intersect(const Ray &ray, IndexType idx,
|
||||
* Float mint, Float maxt, Float &t, void *tmp);
|
||||
*
|
||||
* This class implements an epsilon-free version of the optimized ray
|
||||
* traversal algorithm (TA^B_{rec}), which is explained in Vlastimil
|
||||
* Havran's PhD thesis "Heuristic Ray Shooting Algorithms".
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
*/
|
||||
template <typename Derived>
|
||||
class SAHKDTree4D : public GenericKDTree<AABB4, SurfaceAreaHeuristic4, Derived> {
|
||||
public:
|
||||
typedef typename KDTreeBase<AABB4>::SizeType SizeType;
|
||||
typedef typename KDTreeBase<AABB4>::IndexType IndexType;
|
||||
typedef typename KDTreeBase<AABB4>::KDNode KDNode;
|
||||
|
||||
protected:
|
||||
void buildInternal() {
|
||||
SizeType primCount = this->cast()->getPrimitiveCount();
|
||||
KDLog(EInfo, "Constructing a 4D SAH kd-tree (%i primitives) ..", primCount);
|
||||
GenericKDTree<AABB4, SurfaceAreaHeuristic4, Derived>::buildInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Hashed mailbox implementation
|
||||
*/
|
||||
struct HashedMailbox {
|
||||
inline HashedMailbox() {
|
||||
memset(entries, 0xFF, sizeof(IndexType)*MTS_KD_MAILBOX_SIZE);
|
||||
}
|
||||
|
||||
inline void put(IndexType primIndex) {
|
||||
entries[primIndex & MTS_KD_MAILBOX_MASK] = primIndex;
|
||||
}
|
||||
|
||||
inline bool contains(IndexType primIndex) const {
|
||||
return entries[primIndex & MTS_KD_MAILBOX_MASK] == primIndex;
|
||||
}
|
||||
|
||||
IndexType entries[MTS_KD_MAILBOX_SIZE];
|
||||
};
|
||||
|
||||
/// Ray traversal stack entry for Havran-style incoherent ray tracing
|
||||
struct KDStackEntryHavran {
|
||||
/* Pointer to the far child */
|
||||
const KDNode * __restrict node;
|
||||
/* Distance traveled along the ray (entry or exit) */
|
||||
Float t;
|
||||
/* Previous stack item */
|
||||
uint32_t prev;
|
||||
/* Associated point */
|
||||
Point p;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Ray tracing kd-tree traversal loop (Havran variant)
|
||||
*
|
||||
* This is generally the most robust and fastest traversal routine
|
||||
* of the methods implemented in this class.
|
||||
*/
|
||||
template<bool shadowRay> FINLINE
|
||||
bool rayIntersectHavran(const Ray &ray, Float mint, Float maxt,
|
||||
Float &t, void *temp) const {
|
||||
KDStackEntryHavran stack[MTS_KD_MAXDEPTH];
|
||||
#if 0
|
||||
static const int prevAxisTable[] = { 2, 0, 1 };
|
||||
static const int nextAxisTable[] = { 1, 2, 0 };
|
||||
#endif
|
||||
|
||||
#if defined(MTS_KD_MAILBOX_ENABLED)
|
||||
HashedMailbox mailbox;
|
||||
#endif
|
||||
|
||||
/* Set up the entry point */
|
||||
uint32_t enPt = 0;
|
||||
stack[enPt].t = mint;
|
||||
stack[enPt].p = ray(mint);
|
||||
|
||||
/* Set up the exit point */
|
||||
uint32_t exPt = 1;
|
||||
stack[exPt].t = maxt;
|
||||
stack[exPt].p = ray(maxt);
|
||||
stack[exPt].node = NULL;
|
||||
|
||||
bool foundIntersection = false;
|
||||
const KDNode * __restrict currNode = this->m_nodes;
|
||||
while (currNode != NULL) {
|
||||
while (EXPECT_TAKEN(!currNode->isLeaf())) {
|
||||
const Float splitVal = (Float) currNode->getSplit();
|
||||
const int axis = currNode->getAxis();
|
||||
const KDNode * __restrict farChild;
|
||||
|
||||
if (axis == 3) {
|
||||
if (ray.time <= splitVal)
|
||||
currNode = currNode->getLeft();
|
||||
else
|
||||
currNode = currNode->getRight();
|
||||
continue;
|
||||
} else if (stack[enPt].p[axis] <= splitVal) {
|
||||
if (stack[exPt].p[axis] <= splitVal) {
|
||||
/* Cases N1, N2, N3, P5, Z2 and Z3 (see thesis) */
|
||||
currNode = currNode->getLeft();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Typo in Havran's thesis:
|
||||
(it specifies "stack[exPt].p == splitVal", which
|
||||
is clearly incorrect) */
|
||||
if (stack[enPt].p[axis] == splitVal) {
|
||||
/* Case Z1 */
|
||||
currNode = currNode->getRight();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Case N4 */
|
||||
currNode = currNode->getLeft();
|
||||
farChild = currNode + 1; // getRight()
|
||||
} else { /* stack[enPt].p[axis] > splitVal */
|
||||
if (splitVal < stack[exPt].p[axis]) {
|
||||
/* Cases P1, P2, P3 and N5 */
|
||||
currNode = currNode->getRight();
|
||||
continue;
|
||||
}
|
||||
/* Case P4 */
|
||||
farChild = currNode->getLeft();
|
||||
currNode = farChild + 1; // getRight()
|
||||
}
|
||||
|
||||
/* Cases P4 and N4 -- calculate the distance to the split plane */
|
||||
Float distToSplit = (splitVal - ray.o[axis]) * ray.dRcp[axis];
|
||||
|
||||
/* Set up a new exit point */
|
||||
const uint32_t tmp = exPt++;
|
||||
if (exPt == enPt) /* Do not overwrite the entry point */
|
||||
++exPt;
|
||||
|
||||
KDAssert(exPt < MTS_KD_MAXDEPTH);
|
||||
stack[exPt].prev = tmp;
|
||||
stack[exPt].t = distToSplit;
|
||||
stack[exPt].node = farChild;
|
||||
|
||||
#if 1
|
||||
/* Intrestingly, this appears to be faster than the
|
||||
original code with the prevAxis & nextAxis table */
|
||||
stack[exPt].p = ray(distToSplit);
|
||||
stack[exPt].p[axis] = splitVal;
|
||||
#else
|
||||
const int nextAxis = nextAxisTable[axis];
|
||||
const int prevAxis = prevAxisTable[axis];
|
||||
stack[exPt].p[axis] = splitVal;
|
||||
stack[exPt].p[nextAxis] = ray.o[nextAxis]
|
||||
+ distToSplit*ray.d[nextAxis];
|
||||
stack[exPt].p[prevAxis] = ray.o[prevAxis]
|
||||
+ distToSplit*ray.d[prevAxis];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Reached a leaf node */
|
||||
for (IndexType entry=currNode->getPrimStart(),
|
||||
last = currNode->getPrimEnd(); entry != last; entry++) {
|
||||
const IndexType primIdx = this->m_indices[entry];
|
||||
|
||||
#if defined(MTS_KD_MAILBOX_ENABLED)
|
||||
if (mailbox.contains(primIdx))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
bool result;
|
||||
if (!shadowRay)
|
||||
result = this->cast()->intersect(ray, primIdx, mint, maxt, t, temp);
|
||||
else
|
||||
result = this->cast()->intersect(ray, primIdx, mint, maxt);
|
||||
|
||||
if (result) {
|
||||
if (shadowRay)
|
||||
return true;
|
||||
maxt = t;
|
||||
foundIntersection = true;
|
||||
}
|
||||
|
||||
#if defined(MTS_KD_MAILBOX_ENABLED)
|
||||
mailbox.put(primIdx);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stack[exPt].t > maxt)
|
||||
break;
|
||||
|
||||
/* Pop from the stack and advance to the next node on the interval */
|
||||
enPt = exPt;
|
||||
currNode = stack[exPt].node;
|
||||
exPt = stack[enPt].prev;
|
||||
}
|
||||
|
||||
return foundIntersection;
|
||||
}
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __SAH_KDTREE4_H */
|
|
@ -133,7 +133,7 @@ public:
|
|||
int sceneResID, int sensorResID, int samplerResID);
|
||||
|
||||
/// Write out the current (partially rendered) image
|
||||
void flush();
|
||||
void flush(RenderQueue *queue, const RenderJob *job);
|
||||
|
||||
/**
|
||||
* \brief Cancel a running rendering job
|
||||
|
@ -1096,11 +1096,9 @@ public:
|
|||
/// Return the scene's normal shapes (including triangular meshes)
|
||||
inline const ref_vector<Shape> &getShapes() const { return m_shapes; }
|
||||
|
||||
/**
|
||||
* \brief Return the scene's shapes (including triangular meshes)
|
||||
*/
|
||||
/// Return a set of special shapes related to emitter/sensor geometry in bidirectional renderings
|
||||
inline ref_vector<Shape> &getSpecialShapes() { return m_specialShapes; }
|
||||
/// Return the scene's shapes (including triangular meshes)
|
||||
/// Return a set of special shapes related to emitter/sensor geometry in bidirectional renderings
|
||||
inline const ref_vector<Shape> &getSpecialShapes() const { return m_specialShapes; }
|
||||
|
||||
/// Return the scene's emitters
|
||||
|
|
|
@ -68,6 +68,9 @@ private:
|
|||
# pragma warning( pop )
|
||||
#endif
|
||||
|
||||
/// Push a cleanup handler to be executed after loading the scene is done
|
||||
extern MTS_EXPORT_RENDER void pushSceneCleanupHandler(void (*cleanup)());
|
||||
|
||||
/**
|
||||
* \brief XML parser for Mitsuba scene files. To be used with the
|
||||
* SAX interface of Xerces-C++.
|
||||
|
@ -133,8 +136,7 @@ protected:
|
|||
private:
|
||||
struct ParseContext {
|
||||
inline ParseContext(ParseContext *_parent)
|
||||
: parent(_parent) {
|
||||
}
|
||||
: parent(_parent) { }
|
||||
|
||||
ParseContext *parent;
|
||||
Properties properties;
|
||||
|
@ -155,7 +157,8 @@ private:
|
|||
EBoolean, EString, ETranslate, ERotate,
|
||||
ELookAt, EScale, EMatrix, EPoint,
|
||||
EVector, ERGB, ESRGB, EBlackBody,
|
||||
ESpectrum, ETransform, EInclude, EAlias
|
||||
ESpectrum, ETransform, EAnimation,
|
||||
EInclude, EAlias
|
||||
};
|
||||
|
||||
typedef std::pair<ETag, const Class *> TagEntry;
|
||||
|
@ -170,6 +173,7 @@ private:
|
|||
std::stack<ParseContext> m_context;
|
||||
TagMap m_tags;
|
||||
Transform m_transform;
|
||||
ref<AnimatedTransform> m_animatedTransform;
|
||||
bool m_isIncludedFile;
|
||||
};
|
||||
|
||||
|
|
|
@ -258,9 +258,15 @@ public:
|
|||
/// Return the time value of the shutter opening event
|
||||
inline Float getShutterOpen() const { return m_shutterOpen; }
|
||||
|
||||
/// Set the time value of the shutter opening event
|
||||
void setShutterOpen(Float time) { m_shutterOpen = time; }
|
||||
|
||||
/// Return the length, for which the shutter remains open
|
||||
inline Float getShutterOpenTime() const { return m_shutterOpenTime; }
|
||||
|
||||
/// Set the length, for which the shutter remains open
|
||||
void setShutterOpenTime(Float time);
|
||||
|
||||
/**
|
||||
* \brief Does the method \ref sampleRay() require a uniformly distributed
|
||||
* sample for the time-dependent component?
|
||||
|
@ -370,21 +376,29 @@ protected:
|
|||
*/
|
||||
class MTS_EXPORT_RENDER ProjectiveCamera : public Sensor {
|
||||
public:
|
||||
using Sensor::getWorldTransform;
|
||||
|
||||
/// Return the world-to-view (aka "view") transformation at time \c t
|
||||
inline const Transform getViewTransform(Float t) const {
|
||||
return getWorldTransform()->eval(t).inverse();
|
||||
}
|
||||
|
||||
/// Return the view-to-world transformation at time \c t
|
||||
inline const Transform getInverseViewTransform(Float t) const {
|
||||
inline const Transform getWorldTransform(Float t) const {
|
||||
return getWorldTransform()->eval(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Overwrite the inverse world-to-view transformation
|
||||
* \brief Overwrite the view-to-world transformation
|
||||
* with a static (i.e. non-animated) transformation.
|
||||
*/
|
||||
virtual void setInverseViewTransform(const Transform &trafo);
|
||||
void setWorldTransform(const Transform &trafo);
|
||||
|
||||
/**
|
||||
* \brief Overwrite the view-to-world transformation
|
||||
* with an animated transformation
|
||||
*/
|
||||
void setWorldTransform(AnimatedTransform *trafo);
|
||||
|
||||
/**
|
||||
* \brief Return a projection matrix suitable for rendering the
|
||||
|
|
|
@ -193,6 +193,9 @@ public:
|
|||
/**
|
||||
* \brief Return the shape's surface area
|
||||
*
|
||||
* Assumes that the object is not undergoing some kind of
|
||||
* time-dependent scaling.
|
||||
*
|
||||
* The default implementation throws an exception
|
||||
*/
|
||||
virtual Float getSurfaceArea() const;
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
|
||||
#if defined(SINGLE_PRECISION)
|
||||
/// 32 byte temporary storage for intersection computations
|
||||
#define MTS_KD_INTERSECTION_TEMP 32
|
||||
#else
|
||||
#define MTS_KD_INTERSECTION_TEMP 64
|
||||
#else
|
||||
#define MTS_KD_INTERSECTION_TEMP 128
|
||||
#endif
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
|
|
@ -47,6 +47,12 @@ public:
|
|||
virtual bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
|
||||
int sceneResID, int cameraResID, int samplerResID) = 0;
|
||||
|
||||
/// Selectively activate/deactivate the subsurface integrator
|
||||
inline void setActive(bool active) { m_active = active; }
|
||||
|
||||
/// Return whether or not the subsurface integrator is currently active
|
||||
inline bool isActive() const { return m_active; }
|
||||
|
||||
/// Cancel any running pre-process tasks
|
||||
virtual void cancel();
|
||||
|
||||
|
@ -75,6 +81,7 @@ protected:
|
|||
virtual ~Subsurface();
|
||||
protected:
|
||||
std::vector<Shape *> m_shapes;
|
||||
bool m_active;
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
|