Compare commits

..
64 Commits
Author SHA1 Message Date
Sven Woop 86dbc8a437 fixed comments 2018-12-13 08:41:14 +01:00
Sven Woop 4c93274a31 added support for arbitrary SAH block size 2018-12-13 08:39:06 +01:00
Sven Woop bd7ea15f50 replaced logBlockSize by sahBlockSize 2018-12-13 08:22:12 +01:00
Sven Woop 1df9591a8c replaced logBlockSize by sahBlockSize 2018-12-13 07:53:13 +01:00
Sven Woop 23753277fa regenerated documentation 2018-11-22 07:18:21 +01:00
Sven Woop 95053e8c6e setting version to v3.3.0 2018-11-22 07:16:52 +01:00
Sven Woop 0ff0a6909b Merge branch 'devel' of gitlab.com:sdvis/embree into devel 2018-11-21 07:15:17 +01:00
Sven Woop 40e445ade8 setting CMP0042 policy to NEW by default 2018-11-21 07:15:06 +01:00
Sven Woop 8c08b5c5b5 bugfix in open_sequential function, this codepath is currently disabled 2018-11-20 05:39:10 +01:00
Sven Woop a07e9b0c5c Revert "Applied bugfix for missed perfectly axis aligned motion blurred"
This issue is already worked around in the setBounds function of
BVH.

This reverts commit 17a17f7e18.
2018-11-19 17:45:39 +01:00
Sven Woop 0f4f821f76 added documentation for motion blur time range 2018-11-19 08:31:50 +01:00
Sven Woop cf4d9e9f62 Merge branch 'devel' into swoop 2018-11-19 07:54:14 +01:00
Sven Woop d25f7b0ac2 moved previous changelog update to doc/src/changelog.md 2018-11-09 11:03:18 +01:00
Tim Rowley 15caf3fd1b Fix black tutorial windows on macOS 10.14 until moved. 2018-11-07 10:25:32 -06:00
Sven Woop 0eb47c2c6b bugfixes in ambient occlusion shader (--shader ao) 2018-11-06 08:16:03 +01:00
Sven Woop 9de546d581 Fixed crash with pathtracer when using --shader ao command line 2018-11-06 08:00:40 +01:00
Sven Woop 33bd19d2a3 setting version to v3.2.5-alpha.0 2018-11-06 07:45:17 +01:00
Sven Woop 4e1a7741fb Fixed segfault of pathtracer when invoking with --triangle-sphere command line option. 2018-11-06 07:44:19 +01:00
Johannes Günther e2f4851405 Fix typo&links (vs1[24]->vc1[24]), package correct tbb.dll for vc14 2018-10-29 14:29:15 +01:00
Sven Woop 17a17f7e18 Applied bugfix for missed perfectly axis aligned motion blurred
geometry also to time range implementation for motion blur.
2018-09-11 07:00:39 +02:00
Sven Woop b27a31f572 Merge branch 'devel' into swoop 2018-09-11 06:57:54 +02:00
Sven Woop a7772b05aa changed model hash to include time segment mblur test for instances 2018-09-06 10:31:49 +02:00
Sven Woop 03f24bbba5 fixes to scenegraph to support time range for instances 2018-09-06 10:29:45 +02:00
Sven Woop d2db02fa10 bugfix in time range for motion blur geometry of instances 2018-09-06 09:30:25 +02:00
Attila Afra 80c0fae902 cleanup 2018-07-13 17:38:12 +03:00
Attila Afra fd6eca502f fixed bug in temporal splitting 2018-07-13 17:21:00 +03:00
cbenthin a1c750b5a2 merged devel into swoop 2018-07-11 16:46:56 +02:00
Attila Afra 226f9e1fb5 fixed bug in getTimeSegmentRange 2018-07-11 14:15:30 +03:00
cbenthin ef9dd1951d version v3.3.0-alpha.0 2018-06-28 11:10:14 +02:00
Sven Woop a6527de9c9 updates to changelog, added geometry mblur time range 2018-05-28 10:10:58 +02:00
Sven Woop 9805370657 cleanups 2018-05-28 10:08:34 +02:00
Sven Woop ff669ab8f4 bugfix in createLargeLeaf for object time range mblur builder 2018-05-28 09:24:14 +02:00
Sven Woop 4efa364c7b bugfix in BuildRecord construction for object time range mblur builder 2018-05-28 09:07:18 +02:00
Sven Woop ca932f7669 bugfix in time_range handling, have to clip time range when constructing SetMB 2018-05-28 08:25:30 +02:00
Sven Woop 7297e6ffff cleanups 2018-05-28 07:46:00 +02:00
Sven Woop b04f338936 fixed bug with singleTimeSegment feature, however, this is not used anymore 2018-05-28 07:29:02 +02:00
Sven Woop bb4cd86ea4 using mblur time range tests 2018-05-25 14:48:06 +02:00
Sven Woop ba404619cc added grid mesh support to viewer_stream 2018-05-25 14:43:05 +02:00
Sven Woop a88881677e fixed various bugs where time_range was not properly copied 2018-05-25 14:39:38 +02:00
Sven Woop 7b7c88337d bugfix in --convert-triangles-to-quads, time range was not copied 2018-05-25 14:21:51 +02:00
Sven Woop a9b96ac13f added mblur_time_range_grid.xml 2018-05-25 14:09:39 +02:00
Sven Woop 0e27f93cb2 bugfix for mblur time range of grids 2018-05-25 14:09:02 +02:00
Sven Woop 4e725e928b added GridMesh support to XML loader 2018-05-25 13:46:32 +02:00
Sven Woop d9fd88e841 fixing mblur time range for quads 2018-05-25 13:41:17 +02:00
Sven Woop abf293aa0a adde mblur_time_range_line.xml 2018-05-25 13:28:08 +02:00
Sven Woop b71f37e1f6 added geometry time range support for curves 2018-05-25 13:26:11 +02:00
Sven Woop 0eabcdddd3 added geometry time range support to all other primitives, except curves everything should be working now 2018-05-25 07:47:40 +02:00
Sven Woop 7b8fa2e8a2 further disabling of buildSingleSegment 2018-05-25 07:13:32 +02:00
Sven Woop a72873c854 bugfix in filtering of non overlapping time ranges 2018-05-23 12:29:38 +02:00
Sven Woop d5e09d228d cleanups 2018-05-23 12:25:59 +02:00
Sven Woop 60b0c0154f bugfix in linear bounds calculation when time ranges were present 2018-05-23 12:17:13 +02:00
Sven Woop 5a7230da1f added triangle_msmblur_time_range.xml 2018-05-23 09:57:12 +02:00
Sven Woop a8dc2540de fixed bug in comment parsing 2018-05-23 09:31:52 +02:00
Sven Woop 03f654c62e optimized trianglei for mblur to only support single geomID 2018-05-23 09:11:52 +02:00
Sven Woop 7aeb056b32 added assertion in msmblur leaf creation to check that all geomIDs are identical 2018-05-23 09:02:48 +02:00
Sven Woop 4262431328 disabling buildSingleSegment in bvh_builder_sah_mb.cpp 2018-05-23 08:58:24 +02:00
Sven Woop 11d5e26d82 properly creating time bounding node when time bounds have shrunken 2018-05-23 08:47:02 +02:00
Sven Woop 3ae221bf73 properly extending time_range during split 2018-05-23 08:07:12 +02:00
Sven Woop f3b787a0ea msmblur builder creates leaves with single geometry only 2018-05-23 07:34:24 +02:00
Sven Woop 0ec8f6a299 filtering out primitives which are not valid in current time interval 2018-05-15 14:24:47 +02:00
Sven Woop 4be6966f63 added TimeRange node to XML format 2018-05-15 12:43:42 +02:00
Sven Woop 49fab5e8e0 assigning mblur time debugging to HOME/END keys 2018-05-15 11:22:47 +02:00
Sven Woop a8ee444842 first attempt to get extended motion blur working for triangles 2018-05-15 11:19:19 +02:00
Sven Woop d710ab6245 added rtcSetGeometryTimeRange API function 2018-05-15 08:22:25 +02:00
92 changed files with 2101 additions and 734 deletions
+4 -4
View File
@@ -465,8 +465,8 @@ nightly-linux-x64-RelWithDebInfo-CLANG4-ISPC1.9.2-AVX2-TBB2017-INSTANCE:
# Release Builds
####################################################################
release-windows-x64-Release-ICC17-VS12-ISPC1.9.2-TBB2017-PACKAGE-ZIP:
script: "python scripts\\test.py platform:x64 build:Release compiler:ICC17-VS12 ispc:ispc1.9.2 isas:SSE2-SSE42-AVX-AVX2-AVX512SKX tasking:TBB2017 intensity:4 package:ZIP"
release-windows-x64-Release-ICC17-VC12-ISPC1.9.2-TBB2017-PACKAGE-ZIP:
script: "python scripts\\test.py platform:x64 build:Release compiler:ICC17-VC12 ispc:ispc1.9.2 isas:SSE2-SSE42-AVX-AVX2-AVX512SKX tasking:TBB2017 intensity:4 package:ZIP"
tags: [win7, icc17]
only: [web]
artifacts:
@@ -475,8 +475,8 @@ release-windows-x64-Release-ICC17-VS12-ISPC1.9.2-TBB2017-PACKAGE-ZIP:
when: always
expire_in: 2 mos
release-windows-x64-Release-ICC17-VS14-ISPC1.9.2-TBB2017-PACKAGE-ZIP:
script: "python scripts\\test.py platform:x64 build:Release compiler:ICC17-VS14 ispc:ispc1.9.2 isas:SSE2-SSE42-AVX-AVX2-AVX512SKX tasking:TBB2017 intensity:4 package:ZIP"
release-windows-x64-Release-ICC17-VC14-ISPC1.9.2-TBB2017-PACKAGE-ZIP:
script: "python scripts\\test.py platform:x64 build:Release compiler:ICC17-VC14 ispc:ispc1.9.2 isas:SSE2-SSE42-AVX-AVX2-AVX512SKX tasking:TBB2017 intensity:4 package:ZIP"
tags: [win7, icc17]
only: [web]
artifacts:
+8
View File
@@ -1,6 +1,14 @@
Version History
---------------
### New Features in Embree 3.3.0
- Added support for motion blur time range per geometry. This way geometries
can appear and disappear during the camera shutter and time steps do not have
to start and end at camera shutter interval boundaries.
- Fixed crash with pathtracer when using --triangle-sphere command line.
- Fixed crash with pathtracer when using --shader ao command line.
- Fixed tutorials showing a black window on macOS 10.14 until moved.
### New Features in Embree 3.2.4
- Fixed compile issues with ICC 2019.
- Released ZIP files for Windows are now provided in a
+3 -3
View File
@@ -15,8 +15,8 @@
## ======================================================================== ##
SET(EMBREE_VERSION_MAJOR 3)
SET(EMBREE_VERSION_MINOR 2)
SET(EMBREE_VERSION_PATCH 4)
SET(EMBREE_VERSION_MINOR 3)
SET(EMBREE_VERSION_PATCH 0)
SET(EMBREE_VERSION_NOTE "")
SET(EMBREE_VERSION ${EMBREE_VERSION_MAJOR}.${EMBREE_VERSION_MINOR}.${EMBREE_VERSION_PATCH})
@@ -75,7 +75,7 @@ IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif()
if (POLICY CMP0042)
cmake_policy(SET CMP0042 OLD)
cmake_policy(SET CMP0042 NEW)
endif()
ENDIF(COMMAND cmake_policy)
+1 -1
View File
@@ -16,7 +16,7 @@
set(CTEST_PROJECT_NAME "Embree")
set(CTEST_NIGHTLY_START_TIME "22:00:00 UTC")
set(TEST_MODELS_HASH a1b183a3b76eb40c4c2e6a2d4dc5ca08090d8400)
set(TEST_MODELS_HASH ba1bd24186ccdf939d2e749a514f81718f3a2b20)
IF (NOT CTEST_DROP_SITE)
set(CTEST_DROP_METHOD "http")
+44 -34
View File
@@ -1,4 +1,4 @@
% Embree: High Performance Ray Tracing Kernels 3.2.4
% Embree: High Performance Ray Tracing Kernels 3.3.0
% Intel Corporation
Embree Overview
@@ -85,9 +85,9 @@ Windows MSI Installer
---------------------
You can install the Embree library using the Windows MSI installer
[embree-3.2.4-x64.vs12.msi](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x64.vs12.msi). This
[embree-3.3.0-x64.vc12.msi](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x64.vc12.msi). This
will install the 64-bit Embree version by default in `Program
Files\Intel\Embree v3.2.4 x64`.
Files\Intel\Embree v3.3.0 x64`.
You have to set the path to the `bin` folders manually to your `PATH`
environment variable for applications to find Embree.
@@ -95,20 +95,20 @@ environment variable for applications to find Embree.
To compile applications with Embree using CMake, please have a look at
the `find_embree` tutorial. To compile this tutorial, you need to set
the `embree_DIR` CMake variable of this tutorial to `Program
Files\Intel\Embree v3.2.4 x64`.
Files\Intel\Embree v3.3.0 x64`.
To uninstall Embree, open `Programs and Features` by clicking the
`Start button`, clicking `Control Panel`, clicking `Programs`, and
then clicking `Programs and Features`. Select `Embree
3.2.4 x64` and uninstall it.
3.3.0 x64` and uninstall it.
Windows ZIP File
-----------------
Embree linked against Visual Studio 2013
[embree-3.2.4.x64.vs12.windows.zip](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x64.vs12.windows.zip)
[embree-3.3.0.x64.vc12.windows.zip](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x64.vc12.windows.zip)
and Visual Studio 2015
[embree-3.2.4.x64.vs14.windows.zip](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x64.vs14.windows.zip)
[embree-3.3.0.x64.vc14.windows.zip](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x64.vc14.windows.zip)
are provided as a ZIP file. After unpacking this ZIP file, you should
set the path to the `lib` folder manually to your `PATH` environment
variable for applications to find Embree. To compile applications with
@@ -122,17 +122,17 @@ Linux RPMs
----------
Uncompress the `tar.gz` file
[embree-3.2.4.x86_64.rpm.tar.gz](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x86_64.rpm.tar.gz)
[embree-3.3.0.x86_64.rpm.tar.gz](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x86_64.rpm.tar.gz)
to obtain the individual RPM files:
tar xzf embree-3.2.4.x86_64.rpm.tar.gz
tar xzf embree-3.3.0.x86_64.rpm.tar.gz
To install Embree using the RPM packages on your Linux system, type
the following:
sudo rpm --install embree3-lib-3.2.4-1.x86_64.rpm
sudo rpm --install embree3-devel-3.2.4-1.noarch.rpm
sudo rpm --install embree3-examples-3.2.4-1.x86_64.rpm
sudo rpm --install embree3-lib-3.3.0-1.x86_64.rpm
sudo rpm --install embree3-devel-3.3.0-1.noarch.rpm
sudo rpm --install embree3-examples-3.3.0-1.x86_64.rpm
You also have to install the Intel® Threading Building Blocks (TBB)
using `yum`:
@@ -144,13 +144,13 @@ filed into DEB files using the `alien` tool:
sudo apt-get install alien dpkg-dev debhelper build-essential
sudo alien embree3-lib-3.2.4-1.x86_64.rpm
sudo alien embree3-devel-3.2.4-1.noarch.rpm
sudo alien embree3-examples-3.2.4-1.x86_64.rpm
sudo alien embree3-lib-3.3.0-1.x86_64.rpm
sudo alien embree3-devel-3.3.0-1.noarch.rpm
sudo alien embree3-examples-3.3.0-1.x86_64.rpm
sudo dpkg -i embree3-lib_3.2.4-2_amd64.deb
sudo dpkg -i embree3-devel_3.2.4-2_all.deb
sudo dpkg -i embree3-examples_3.2.4-2_amd64.deb
sudo dpkg -i embree3-lib_3.3.0-2_amd64.deb
sudo dpkg -i embree3-devel_3.3.0-2_all.deb
sudo dpkg -i embree3-examples_3.3.0-2_amd64.deb
Also install the Intel® Threading Building Blocks (TBB) using `apt-get`:
@@ -176,20 +176,20 @@ the tutorials to start them.
To uninstall Embree, just execute the following:
sudo rpm --erase embree3-lib-3.2.4-1.x86_64
sudo rpm --erase embree3-devel-3.2.4-1.noarch
sudo rpm --erase embree3-examples-3.2.4-1.x86_64
sudo rpm --erase embree3-lib-3.3.0-1.x86_64
sudo rpm --erase embree3-devel-3.3.0-1.noarch
sudo rpm --erase embree3-examples-3.3.0-1.x86_64
Linux tar.gz Files
------------------
The Linux version of Embree is also delivered as a `tar.gz` file:
[embree-3.2.4.x86_64.linux.tar.gz](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x86_64.linux.tar.gz). Unpack this file using `tar` and source the provided `embree-vars.sh` (if you
[embree-3.3.0.x86_64.linux.tar.gz](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x86_64.linux.tar.gz). Unpack this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the
C shell) to set up the environment properly:
tar xzf embree-3.2.4.x86_64.linux.tar.gz
source embree-3.2.4.x86_64.linux/embree-vars.sh
tar xzf embree-3.3.0.x86_64.linux.tar.gz
source embree-3.3.0.x86_64.linux/embree-vars.sh
If you want to ship Embree with your application, best use the Embree
version provided in the `tar.gz` file.
@@ -202,7 +202,7 @@ macOS PKG Installer
To install the Embree library on your macOS system use the
provided package installer inside
[embree-3.2.4.x86_64.dmg](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x86_64.dmg). This
[embree-3.3.0.x86_64.dmg](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x86_64.dmg). This
will install Embree by default into `/opt/local/lib` and
`/opt/local/include` directories. The Embree tutorials are installed
into the `/Applications/Embree3` directory.
@@ -224,12 +224,12 @@ macOS tar.gz file
-----------------
The macOS version of Embree is also delivered as a `tar.gz` file:
[embree-3.2.4.x86_64.macosx.tar.gz](https://github.com/embree/embree/releases/download/v3.2.4/embree-3.2.4.x86_64.macosx.tar.gz). Unpack this file using `tar` and source the provided `embree-vars.sh` (if you
[embree-3.3.0.x86_64.macosx.tar.gz](https://github.com/embree/embree/releases/download/v3.3.0/embree-3.3.0.x86_64.macosx.tar.gz). Unpack this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the
C shell) to set up the environment properly:
tar xzf embree-3.2.4.x64.macosx.tar.gz
source embree-3.2.4.x64.macosx/embree-vars.sh
tar xzf embree-3.3.0.x64.macosx.tar.gz
source embree-3.3.0.x64.macosx/embree-vars.sh
If you want to ship Embree with your application, please use the Embree
library of the provided `tar.gz` file. The library name of that Embree
@@ -700,14 +700,19 @@ assign a geometry ID) or using the `rtcAttachGeometryById` function
to a single scene at a time.
All geometry types support multi-segment motion blur with an arbitrary
number of equidistant time steps (in the range of 2 to 129). Each
geometry can have a different number of time steps. The motion blur
geometry is defined by linearly interpolating the geometries of
neighboring time steps. To construct a motion blur geometry, first the
number of time steps of the geometry must be specified using the
number of equidistant time steps (in the range of 2 to 129) inside a
user specified time range. Each geometry can have a different number
of time steps and a different time range. The motion blur geometry is
defined by linearly interpolating the geometries of neighboring time
steps. To construct a motion blur geometry, first the number of time
steps of the geometry must be specified using the
`rtcSetGeometryTimeStepCount` function, and then a vertex buffer for
each time step must be bound, e.g. using the
`rtcSetSharedGeometryBuffer` function.
`rtcSetSharedGeometryBuffer` function. Optionally, a time range
defining the start (and end time) of the first (and last) time step
can be set using the `rtcSetGeometryTimeRange` function. This feature
will also allow geometries to appear and disappear during the camera
shutter time if the time range is a sub range of [0,1].
The API supports per-geometry filter callback functions (see
`rtcSetGeometryIntersectFilterFunction` and
@@ -1235,6 +1240,11 @@ Embree API Reference
```
## rtcSetGeometryTimeRange
``` {include=src/api/rtcSetGeometryTimeRange.md}
```
## rtcSetGeometryVertexAttributeCount
``` {include=src/api/rtcSetGeometryVertexAttributeCount.md}
```
+3 -6
View File
@@ -51,13 +51,10 @@ IF (WIN32)
SET(TBB_ARCH ia32)
ENDIF()
IF (MSVC10)
SET(TBB_VCVER vc10)
ELSEIF (MSVC11)
SET(TBB_VCVER vc11)
ELSEIF (MSVC12)
# precompiled TBB packages currently only support VC12 and VC14
IF (MSVC12)
SET(TBB_VCVER vc12)
ELSE()
ELSEIF(MSVC14)
SET(TBB_VCVER vc14)
ENDIF()
+2 -6
View File
@@ -165,13 +165,9 @@ IF(WIN32)
SET(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME} Win32")
ENDIF()
IF (MSVC10)
SET(VCVER vc10)
ELSEIF (MSVC11)
SET(VCVER vc11)
ELSEIF (MSVC12)
IF (MSVC12)
SET(VCVER vc12)
ELSE()
ELSEIF(MSVC14) # also for VC15, which is toolset v141
SET(VCVER vc14)
ENDIF()
+50
View File
@@ -109,6 +109,56 @@ namespace embree
bounds1 = b1;
}
/*! calculates the linear bounds of a primitive for the specified time range */
template<typename BoundsFunc>
__forceinline LBBox(const BoundsFunc& bounds, const BBox1f& time_range_in, const BBox1f& geom_time_range, float geom_time_segments)
{
/* normalize global time_range_in to local geom_time_range */
const BBox1f time_range((time_range_in.lower-geom_time_range.lower)/geom_time_range.size(),
(time_range_in.upper-geom_time_range.lower)/geom_time_range.size());
const float lower = time_range.lower*geom_time_segments;
const float upper = time_range.upper*geom_time_segments;
const float ilowerf = floor(lower);
const float iupperf = ceil(upper);
const float ilowerfc = max(0.0f,ilowerf);
const float iupperfc = min(iupperf,geom_time_segments);
const int ilowerc = (int)ilowerfc;
const int iupperc = (int)iupperfc;
assert(iupperc-ilowerc > 0);
/* this larger iteration range guarantees that we process borders of geom_time_range is (partially) inside time_range_in */
const int ilower_iter = max(-1,(int)ilowerf);
const int iupper_iter = min((int)iupperf,(int)geom_time_segments+1);
const BBox<T> blower0 = bounds(ilowerc);
const BBox<T> bupper1 = bounds(iupperc);
if (iupper_iter-ilower_iter == 1) {
bounds0 = lerp(blower0, bupper1, max(0.0f,lower-ilowerfc));
bounds1 = lerp(bupper1, blower0, max(0.0f,iupperfc-upper));
return;
}
const BBox<T> blower1 = bounds(ilowerc+1);
const BBox<T> bupper0 = bounds(iupperc-1);
BBox<T> b0 = lerp(blower0, blower1, max(0.0f,lower-ilowerfc));
BBox<T> b1 = lerp(bupper1, bupper0, max(0.0f,iupperfc-upper));
for (int i = ilower_iter+1; i < iupper_iter; i++)
{
const float f = (float(i)/geom_time_segments - time_range.lower) / time_range.size();
const BBox<T> bt = lerp(b0, b1, f);
const BBox<T> bi = bounds(i);
const T dlower = min(bi.lower-bt.lower, T(zero));
const T dupper = max(bi.upper-bt.upper, T(zero));
b0.lower += dlower; b1.lower += dlower;
b0.upper += dupper; b1.upper += dupper;
}
bounds0 = b0;
bounds1 = b1;
}
/*! calculates the linear bounds of a primitive for the specified time range */
template<typename BoundsFunc>
__forceinline LBBox(const BoundsFunc& bounds, const range<int>& time_range, int numTimeSegments)
+2
View File
@@ -230,6 +230,8 @@ namespace embree
// __forceinline vuint4 operator *(const vuint4& a, unsigned int b) { return a * vuint4(b); }
// __forceinline vuint4 operator *(unsigned int a, const vuint4& b) { return vuint4(a) * b; }
__forceinline vuint4 operator /(const vuint4& a, const vuint4& b) { return vuint4(a[0]/b[0],a[1]/b[1],a[2]/b[2],a[3]/b[3]); }
__forceinline vuint4 operator &(const vuint4& a, const vuint4& b) { return _mm_and_si128(a, b); }
__forceinline vuint4 operator &(const vuint4& a, unsigned int b) { return a & vuint4(b); }
__forceinline vuint4 operator &(unsigned int a, const vuint4& b) { return vuint4(a) & b; }
+8
View File
@@ -26,6 +26,14 @@ namespace embree
std::string toLowerCase(const std::string& s) { std::string dst(s); std::transform(dst.begin(), dst.end(), dst.begin(), to_lower); return dst; }
std::string toUpperCase(const std::string& s) { std::string dst(s); std::transform(dst.begin(), dst.end(), dst.begin(), to_upper); return dst; }
Vec2f string_to_Vec2f ( std::string str )
{
size_t next = 0;
const float x = std::stof(str,&next); str = str.substr(next+1);
const float y = std::stof(str,&next);
return Vec2f(x,y);
}
Vec3f string_to_Vec3f ( std::string str )
{
size_t next = 0;
+2
View File
@@ -17,6 +17,7 @@
#pragma once
#include "platform.h"
#include "../math/vec2.h"
#include "../math/vec3.h"
namespace embree
@@ -42,5 +43,6 @@ namespace embree
std::string toLowerCase(const std::string& s);
std::string toUpperCase(const std::string& s);
Vec2f string_to_Vec2f ( std::string str );
Vec3f string_to_Vec3f ( std::string str );
}
+16 -6
View File
@@ -111,14 +111,19 @@ assign a geometry ID) or using the `rtcAttachGeometryById` function
to a single scene at a time.
All geometry types support multi-segment motion blur with an arbitrary
number of equidistant time steps (in the range of 2 to 129). Each
geometry can have a different number of time steps. The motion blur
geometry is defined by linearly interpolating the geometries of
neighboring time steps. To construct a motion blur geometry, first the
number of time steps of the geometry must be specified using the
number of equidistant time steps (in the range of 2 to 129) inside a
user specified time range. Each geometry can have a different number
of time steps and a different time range. The motion blur geometry is
defined by linearly interpolating the geometries of neighboring time
steps. To construct a motion blur geometry, first the number of time
steps of the geometry must be specified using the
`rtcSetGeometryTimeStepCount` function, and then a vertex buffer for
each time step must be bound, e.g. using the
`rtcSetSharedGeometryBuffer` function.
`rtcSetSharedGeometryBuffer` function. Optionally, a time range
defining the start (and end time) of the first (and last) time step
can be set using the `rtcSetGeometryTimeRange` function. This feature
will also allow geometries to appear and disappear during the camera
shutter time if the time range is a sub range of [0,1].
The API supports per-geometry filter callback functions (see
`rtcSetGeometryIntersectFilterFunction` and
@@ -646,6 +651,11 @@ Embree API Reference
```
\pagebreak
## rtcSetGeometryTimeRange
``` {include=src/api/rtcSetGeometryTimeRange.md}
```
\pagebreak
## rtcSetGeometryVertexAttributeCount
``` {include=src/api/rtcSetGeometryVertexAttributeCount.md}
```
+52
View File
@@ -0,0 +1,52 @@
% rtcSetGeometryTimeRange(3) | Embree Ray Tracing Kernels 3
#### NAME
rtcSetGeometryTimeRange - sets the time range for a motion blur geometry
#### SYNOPSIS
#include <embree3/rtcore.h>
void rtcSetGeometryTimeRange(
RTCGeometry geometry,
float startTime,
float endTime
);
#### DESCRIPTION
The `rtcSetGeometryTimeRange` function sets a time range which defines
the start (and end time) of the first (and last) time step of a motion
blur geometry. The time range is defined relative to the camera
shutter interval [0,1] but it can be arbitrary. Thus the startTime can
be smaller, equal, or larger 0, indicating a geometry whose animation
definition start before, at, or after the camera shutter
opens. Similar the endTime can be smaller, equal, or larger than 1,
indicating a geometry whose animation definition ends after, at, or
before the camera shutter closes. The startTime has to be smaller or
equal to the endTime.
The default time range when this function is not called is the entire
camera shutter [0,1]. For best performance at most one time segment of
the piece wise linear definition of the motion should fall outside the
shutter window to the left and to the right. Thus do not set the
startTime or endTime too far outside the [0,1] interval for best
performance.
This time range feature will also allow geometries to appear and
disappear during the camera shutter time if the specified time range
is a sub range of [0,1].
Please also have a look at the `rtcSetGeometryTimeStepCount` function
to see how to define the time steps for the specified time range.
#### EXIT STATUS
On failure an error code is set that can be queried using
`rtcDeviceGetError`.
#### SEE ALSO
[rtcSetGeometryTimeStepCount]
+1 -1
View File
@@ -44,4 +44,4 @@ On failure an error code is set that can be queried using
#### SEE ALSO
[rtcNewGeometry]
[rtcNewGeometry], [rtcSetGeometryTimeRange]
+8
View File
@@ -1,6 +1,14 @@
Version History
---------------
### New Features in Embree 3.3.0
- Added support for motion blur time range per geometry. This way geometries
can appear and disappear during the camera shutter and time steps do not have
to start and end at camera shutter interval boundaries.
- Fixed crash with pathtracer when using --triangle-sphere command line.
- Fixed crash with pathtracer when using --shader ao command line.
- Fixed tutorials showing a black window on macOS 10.14 until moved.
### New Features in Embree 3.2.4
- Fixed compile issues with ICC 2019.
- Released ZIP files for Windows are now provided in a
+5 -4
View File
@@ -3,11 +3,12 @@ Downloading Embree
For Windows we provide Embree as MSI installer and ZIP files. For the
ZIP files we have a version where Embree is linked against the Visual
Studio 2013 (vs12) runtime and and Visual Studio 2015 (vs14) runtime:
Studio 2013 (VC12) runtime and and Visual Studio 2015/2017 (VC14)
runtime:
[embree-<EMBREE_VERSION>-x64.vs12.msi](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs12.msi)
[embree-<EMBREE_VERSION>.x64.vs12.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs12.windows.zip)
[embree-<EMBREE_VERSION>.x64.vs14.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs14.windows.zip)
[embree-<EMBREE_VERSION>-x64.vc12.msi](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc12.msi)
[embree-<EMBREE_VERSION>.x64.vc12.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc12.windows.zip)
[embree-<EMBREE_VERSION>.x64.vc14.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc14.windows.zip)
For Linux we provide Embree as RPMs or as a `tar.gz` file:
+3 -3
View File
@@ -5,7 +5,7 @@ Windows MSI Installer
---------------------
You can install the Embree library using the Windows MSI installer
[embree-<EMBREE_VERSION>-x64.vs12.msi](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs12.msi). This
[embree-<EMBREE_VERSION>-x64.vc12.msi](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc12.msi). This
will install the 64-bit Embree version by default in `Program
Files\Intel\Embree v<EMBREE_VERSION> x64`.
@@ -26,9 +26,9 @@ Windows ZIP File
-----------------
Embree linked against Visual Studio 2013
[embree-<EMBREE_VERSION>.x64.vs12.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs12.windows.zip)
[embree-<EMBREE_VERSION>.x64.vc12.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc12.windows.zip)
and Visual Studio 2015
[embree-<EMBREE_VERSION>.x64.vs14.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vs14.windows.zip)
[embree-<EMBREE_VERSION>.x64.vc14.windows.zip](https://github.com/embree/embree/releases/download/v<EMBREE_VERSION>/embree-<EMBREE_VERSION>.x64.vc14.windows.zip)
are provided as a ZIP file. After unpacking this ZIP file, you should
set the path to the `lib` folder manually to your `PATH` environment
variable for applications to find Embree. To compile applications with
+4 -1
View File
@@ -153,9 +153,12 @@ RTC_API void rtcEnableGeometry(RTCGeometry geometry);
RTC_API void rtcDisableGeometry(RTCGeometry geometry);
/* Sets the number of time steps of the geometry. */
/* Sets the number of motion blur time steps of the geometry. */
RTC_API void rtcSetGeometryTimeStepCount(RTCGeometry geometry, unsigned int timeStepCount);
/* Sets the motion blur time range of the geometry. */
RTC_API void rtcSetGeometryTimeRange(RTCGeometry geometry, float startTime, float endTime);
/* Sets the number of vertex attributes of the geometry. */
RTC_API void rtcSetGeometryVertexAttributeCount(RTCGeometry geometry, unsigned int vertexAttributeCount);
+4 -1
View File
@@ -150,9 +150,12 @@ RTC_API void rtcEnableGeometry(RTCGeometry geometry);
RTC_API void rtcDisableGeometry(RTCGeometry geometry);
/* Sets the number of time steps of the geometry. */
/* Sets the number of motion blur time steps of the geometry. */
RTC_API void rtcSetGeometryTimeStepCount(RTCGeometry geometry, uniform unsigned int timeStepCount);
/* Sets the motion blur time range of the geometry. */
RTC_API void rtcSetGeometryTimeRange(RTCGeometry geometry, uniform float startTime, uniform float endTime);
/* Sets the number of vertex attributes of the geometry. */
RTC_API void rtcSetGeometryVertexAttributeCount(RTCGeometry geometry, uniform unsigned int vertexAttributeCount);
+4 -4
View File
@@ -15,7 +15,7 @@
// ======================================================================== //
#define RTC_VERSION_MAJOR 3
#define RTC_VERSION_MINOR 2
#define RTC_VERSION_PATCH 4
#define RTC_VERSION 30204
#define RTC_VERSION_STRING "3.2.4"
#define RTC_VERSION_MINOR 3
#define RTC_VERSION_PATCH 0
#define RTC_VERSION 30300
#define RTC_VERSION_STRING "3.3.0"
+7 -6
View File
@@ -36,12 +36,12 @@ namespace embree
{
/*! default settings */
Settings ()
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8), finished_range_threshold(inf) {}
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8), finished_range_threshold(inf) {}
public:
size_t branchingFactor; //!< branching factor of BVH to build
size_t maxDepth; //!< maximum depth of BVH to build
size_t logBlockSize; //!< log2 of blocksize for SAH heuristic
size_t sahBlockSize; //!< blocksize for SAH heuristic
size_t minLeafSize; //!< minimum size of a leaf
size_t maxLeafSize; //!< maximum size of a leaf
size_t finished_range_threshold; //!< finished range threshold
@@ -102,6 +102,7 @@ namespace embree
/*! checks if all primitives are from the same geometry */
__forceinline bool sameGeometry(const PrimInfoRange& range)
{
if (range.size() == 0) return true;
unsigned int firstGeomID = prims[range.begin()].geomID();
for (size_t i=range.begin()+1; i<range.end(); i++) {
if (prims[i].geomID() != firstGeomID){
@@ -178,14 +179,14 @@ namespace embree
{
/* variable to track the SAH of the best splitting approach */
float bestSAH = inf;
const size_t blocks = (pinfo.size()+(1ull<<cfg.logBlockSize)-1ull) >> cfg.logBlockSize;
const size_t blocks = (pinfo.size()+cfg.sahBlockSize-1) / cfg.sahBlockSize;
const float leafSAH = intCost*float(blocks)*halfArea(pinfo.geomBounds);
/* try standard binning in aligned space */
float alignedObjectSAH = inf;
HeuristicBinningSAH::Split alignedObjectSplit;
if (aligned) {
alignedObjectSplit = alignedHeuristic.find(pinfo,cfg.logBlockSize);
alignedObjectSplit = alignedHeuristic.find(pinfo,cfg.sahBlockSize);
alignedObjectSAH = travCostAligned*halfArea(pinfo.geomBounds) + intCost*alignedObjectSplit.splitSAH();
bestSAH = min(alignedObjectSAH,bestSAH);
}
@@ -197,7 +198,7 @@ namespace embree
if (bestSAH > 0.7f*leafSAH) {
uspace = unalignedHeuristic.computeAlignedSpace(pinfo);
const PrimInfoRange sinfo = unalignedHeuristic.computePrimInfo(pinfo,uspace);
unalignedObjectSplit = unalignedHeuristic.find(sinfo,cfg.logBlockSize,uspace);
unalignedObjectSplit = unalignedHeuristic.find(sinfo,cfg.sahBlockSize,uspace);
unalignedObjectSAH = travCostUnaligned*halfArea(pinfo.geomBounds) + intCost*unalignedObjectSplit.splitSAH();
bestSAH = min(unalignedObjectSAH,bestSAH);
}
@@ -206,7 +207,7 @@ namespace embree
HeuristicStrandSplitSAH::Split strandSplit;
float strandSAH = inf;
if (bestSAH > 0.7f*leafSAH && pinfo.size() <= 256) {
strandSplit = strandHeuristic.find(pinfo,cfg.logBlockSize);
strandSplit = strandHeuristic.find(pinfo,cfg.sahBlockSize);
strandSAH = travCostUnaligned*halfArea(pinfo.geomBounds) + intCost*strandSplit.splitSAH();
bestSAH = min(strandSAH,bestSAH);
}
+97 -26
View File
@@ -126,9 +126,8 @@ namespace embree
const unsigned primID = prim.primID();
const Mesh* mesh = scene->get<Mesh>(geomID);
const LBBox3fa lbounds = mesh->linearBounds(primID, time_range);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
const range<int> tbounds = mesh->timeSegmentRange(time_range);
return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID);
}
// __noinline is workaround for ICC16 bug under MacOSX
@@ -138,9 +137,8 @@ namespace embree
const unsigned primID = prim.primID();
const Mesh* mesh = scene->get<Mesh>(geomID);
const LBBox3fa lbounds = mesh->linearBounds(space, primID, time_range);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
const range<int> tbounds = mesh->timeSegmentRange(time_range);
return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID);
}
__forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const {
@@ -166,9 +164,8 @@ namespace embree
const unsigned primID = prim.primID();
const Geometry* mesh = scene->get(geomID);
const LBBox3fa lbounds = mesh->vlinearBounds(primID, time_range);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
const range<int> tbounds = mesh->timeSegmentRange(time_range);
return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID);
}
__forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const
@@ -177,9 +174,8 @@ namespace embree
const unsigned primID = prim.primID();
const Geometry* mesh = scene->get(geomID);
const LBBox3fa lbounds = mesh->vlinearBounds(space, primID, time_range);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
const range<int> tbounds = mesh->timeSegmentRange(time_range);
return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID);
}
__forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const {
@@ -198,14 +194,14 @@ namespace embree
{
/*! default settings */
Settings ()
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
travCost(1.0f), intCost(1.0f), singleLeafTimeSegment(false),
singleThreadThreshold(1024) {}
public:
size_t branchingFactor; //!< branching factor of BVH to build
size_t maxDepth; //!< maximum depth of BVH to build
size_t logBlockSize; //!< log2 of blocksize for SAH heuristic
size_t sahBlockSize; //!< blocksize for SAH heuristic
size_t minLeafSize; //!< minimum size of a leaf
size_t maxLeafSize; //!< maximum size of a leaf
float travCost; //!< estimated cost of one traversal step
@@ -298,18 +294,18 @@ namespace embree
const Split find(const SetMB& set)
{
/* first try standard object split */
const Split object_split = heuristicObjectSplit.find(set,cfg.logBlockSize);
const Split object_split = heuristicObjectSplit.find(set,cfg.sahBlockSize);
const float object_split_sah = object_split.splitSAH();
/* test temporal splits only when object split was bad */
const float leaf_sah = set.leafSAH(cfg.logBlockSize);
const float leaf_sah = set.leafSAH(cfg.sahBlockSize);
if (object_split_sah < 0.50f*leaf_sah)
return object_split;
/* do temporal splits only if the the time range is big enough */
if (set.time_range.size() > 1.01f/float(set.max_num_time_segments))
{
const Split temporal_split = heuristicTemporalSplit.find(set,cfg.logBlockSize);
const Split temporal_split = heuristicTemporalSplit.find(set,cfg.sahBlockSize);
const float temporal_split_sah = temporal_split.splitSAH();
/* take temporal split if it improved SAH */
@@ -336,6 +332,11 @@ namespace embree
set.deterministic_order();
splitFallback(set,lset,rset);
}
/* split by geometry */
else if (unlikely(split.data == Split::SPLIT_GEOMID)) {
set.deterministic_order();
splitByGeometry(set,lset,rset);
}
else
assert(false);
@@ -345,23 +346,27 @@ namespace embree
/*! finds the best fallback split */
__noinline Split findFallback(const SetMB& set)
{
/* split if primitives are not from same geometry */
if (!sameGeometry(set))
return Split(0.0f,Split::SPLIT_GEOMID);
/* if a leaf can only hold a single time-segment, we might have to do additional temporal splits */
if (cfg.singleLeafTimeSegment)
{
/* test if one primitive has more than one time segment in time range, if so split time */
for (size_t i=set.object_range.begin(); i<set.object_range.end(); i++)
for (size_t i=set.begin(); i<set.end(); i++)
{
const PrimRefMB& prim = (*set.prims)[i];
const range<int> itime_range = getTimeSegmentRange(set.time_range,(float)prim.totalTimeSegments());
const range<int> itime_range = prim.timeSegmentRange(set.time_range);
const int localTimeSegments = itime_range.size();
assert(localTimeSegments > 0);
if (localTimeSegments > 1) {
const int icenter = (itime_range.begin() + itime_range.end())/2;
const float splitTime = float(icenter)/float(prim.totalTimeSegments());
const float splitTime = prim.timeStep(icenter);
return Split(0.0f,(unsigned)Split::SPLIT_TEMPORAL,0,splitTime);
}
}
}
}
/* otherwise return fallback split */
return Split(0.0f,Split::SPLIT_FALLBACK);
@@ -372,8 +377,8 @@ namespace embree
{
mvector<PrimRefMB>& prims = *set.prims;
const size_t begin = set.object_range.begin();
const size_t end = set.object_range.end();
const size_t begin = set.begin();
const size_t end = set.end();
const size_t center = (begin + end)/2;
PrimInfoMB linfo = empty;
@@ -388,6 +393,42 @@ namespace embree
new (&rset) SetMB(rinfo,set.prims,range<size_t>(center,end ),set.time_range);
}
/*! checks if all primitives are from the same geometry */
__forceinline bool sameGeometry(const SetMB& set)
{
if (set.size() == 0) return true;
mvector<PrimRefMB>& prims = *set.prims;
const size_t begin = set.begin();
const size_t end = set.end();
unsigned int firstGeomID = prims[begin].geomID();
for (size_t i=begin+1; i<end; i++) {
if (prims[i].geomID() != firstGeomID){
return false;
}
}
return true;
}
/* split by geometry ID */
void splitByGeometry(const SetMB& set, SetMB& lset, SetMB& rset)
{
assert(set.size() > 1);
mvector<PrimRefMB>& prims = *set.prims;
const size_t begin = set.begin();
const size_t end = set.end();
PrimInfoMB left(empty);
PrimInfoMB right(empty);
unsigned int geomID = prims[begin].geomID();
size_t center = serial_partitioning(prims.data(),begin,end,left,right,
[&] ( const PrimRefMB& prim ) { return prim.geomID() == geomID; },
[ ] ( PrimInfoMB& dst, const PrimRefMB& prim ) { dst.add_primref(prim); });
new (&lset) SetMB(left, set.prims,range<size_t>(begin,center),set.time_range);
new (&rset) SetMB(right,set.prims,range<size_t>(center,end ),set.time_range);
}
const NodeRecordMB4D createLargeLeaf(const BuildRecord& in, Allocator alloc)
{
/* this should never occur but is a fatal error */
@@ -397,8 +438,22 @@ namespace embree
/* replace already found split by fallback split */
const BuildRecordSplit current(BuildRecord(in.prims,in.depth),findFallback(in.prims));
/* special case when directly creating leaf without any splits that could shrink time_range */
bool force_split = false;
if (current.depth == 1 && current.size() > 0)
{
BBox1f c = empty;
BBox1f p = current.prims.time_range;
for (size_t i=current.prims.begin(); i<current.prims.end(); i++) {
mvector<PrimRefMB>& prims = *current.prims.prims;
c.extend(prims[i].time_range);
}
force_split = c.lower > p.lower || c.upper < p.upper;
}
/* create leaf for few primitives */
if (current.size() <= cfg.maxLeafSize && current.split.data != Split::SPLIT_TEMPORAL)
if (current.size() <= cfg.maxLeafSize && current.split.data < Split::SPLIT_ENFORCE && !force_split)
return createLeaf(current,alloc);
/* fill all children by always splitting the largest one */
@@ -413,9 +468,11 @@ namespace embree
for (size_t i=0; i<children.size(); i++)
{
/* ignore leaves as they cannot get split */
if (children[i].size() <= cfg.maxLeafSize && children[i].split.data != Split::SPLIT_TEMPORAL)
if (children[i].size() <= cfg.maxLeafSize && children[i].split.data < Split::SPLIT_ENFORCE && !force_split)
continue;
force_split = false;
/* remember child with largest size */
if (children[i].size() > bestSize) {
bestSize = children[i].size();
@@ -438,6 +495,13 @@ namespace embree
} while (children.size() < cfg.branchingFactor);
/* detect time_ranges that have shrunken */
for (size_t i=0; i<children.size(); i++) {
const BBox1f c = children[i].prims.time_range;
const BBox1f p = in.prims.time_range;
hasTimeSplits |= c.lower > p.lower || c.upper < p.upper;
}
/* create node */
auto node = createNode(alloc, hasTimeSplits);
@@ -470,7 +534,7 @@ namespace embree
const Split csplit = find(current.prims);
/*! compute leaf and split cost */
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.sahBlockSize);
const float splitSAH = cfg.travCost*current.prims.halfArea()+cfg.intCost*csplit.splitSAH();
assert((current.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
@@ -517,6 +581,13 @@ namespace embree
children.split(bestChild,lrecord,rrecord,std::move(new_vector));
}
/* detect time_ranges that have shrunken */
for (size_t i=0; i<children.size(); i++) {
const BBox1f c = children[i].prims.time_range;
const BBox1f p = current.prims.time_range;
hasTimeSplits |= c.lower > p.lower || c.upper < p.upper;
}
/* sort buildrecords for simpler shadow ray traversal */
//std::sort(&children[0],&children[children.size()],std::greater<BuildRecord>()); // FIXME: reduces traversal performance of bvh8.triangle4 (need to verified) !!
+52 -17
View File
@@ -34,12 +34,12 @@ namespace embree
{
/*! default settings */
Settings ()
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8) {}
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8) {}
public:
size_t branchingFactor; //!< branching factor of BVH to build
size_t maxDepth; //!< maximum depth of BVH to build
size_t logBlockSize; //!< log2 of blocksize for SAH heuristic
size_t sahBlockSize; //!< blocksize for SAH heuristic
size_t minLeafSize; //!< minimum size of a leaf
size_t maxLeafSize; //!< maximum size of a leaf
};
@@ -56,7 +56,7 @@ namespace embree
: depth(depth), prims(prims) {}
__forceinline size_t size() const {
return prims.object_range.size();
return prims.size();
}
public:
@@ -122,8 +122,8 @@ namespace embree
__forceinline bool sameGeometry(const SetMB& set)
{
mvector<PrimRefMB>& prims = *set.prims;
unsigned int firstGeomID = prims[set.object_range.begin()].geomID();
for (size_t i=set.object_range.begin()+1; i<set.object_range.end(); i++) {
unsigned int firstGeomID = prims[set.begin()].geomID();
for (size_t i=set.begin()+1; i<set.end(); i++) {
if (prims[i].geomID() != firstGeomID){
return false;
}
@@ -136,8 +136,8 @@ namespace embree
{
mvector<PrimRefMB>& prims = *set.prims;
const size_t begin = set.object_range.begin();
const size_t end = set.object_range.end();
const size_t begin = set.begin();
const size_t end = set.end();
const size_t center = (begin + end)/2;
PrimInfoMB linfo = empty;
@@ -154,9 +154,9 @@ namespace embree
void splitByGeometry(const SetMB& set, SetMB& lset, SetMB& rset)
{
assert(set.object_range.size() > 1);
const size_t begin = set.object_range.begin();
const size_t end = set.object_range.end();
assert(set.size() > 1);
const size_t begin = set.begin();
const size_t end = set.end();
PrimInfoMB linfo(empty);
PrimInfoMB rinfo(empty);
unsigned int geomID = (*set.prims)[begin].geomID();
@@ -175,8 +175,22 @@ namespace embree
if (current.depth > cfg.maxDepth)
throw_RTCError(RTC_ERROR_UNKNOWN,"depth limit reached");
/* special case when directly creating leaf without any splits that could shrink time_range */
bool force_split = false;
if (current.depth == 1 && current.size() > 0)
{
BBox1f c = empty;
BBox1f p = current.prims.time_range;
for (size_t i=current.prims.begin(); i<current.prims.end(); i++) {
mvector<PrimRefMB>& prims = *current.prims.prims;
c.extend(prims[i].time_range);
}
force_split = c.lower > p.lower || c.upper < p.upper;
}
/* create leaf for few primitives */
if (current.size() <= cfg.maxLeafSize && sameGeometry(current.prims))
if (current.size() <= cfg.maxLeafSize && sameGeometry(current.prims) && !force_split)
return createLeaf(current.prims,alloc);
/* fill all children by always splitting the largest one */
@@ -190,9 +204,11 @@ namespace embree
for (unsigned i=0; i<children.size(); i++)
{
/* ignore leaves as they cannot get split */
if (children[i].size() <= cfg.maxLeafSize && sameGeometry(children[i].prims))
if (children[i].size() <= cfg.maxLeafSize && sameGeometry(children[i].prims) && !force_split)
continue;
force_split = false;
/* remember child with largest size */
if (children[i].size() > bestSize) {
bestSize = children[i].size();
@@ -213,8 +229,17 @@ namespace embree
} while (children.size() < cfg.branchingFactor);
/* detect time_ranges that have shrunken */
bool timesplit = false;
for (size_t i=0; i<children.size(); i++) {
const BBox1f c = children[i].prims.time_range;
const BBox1f p = current.prims.time_range;
timesplit |= c.lower > p.lower || c.upper < p.upper;
}
/* create node */
NodeRef node = createAlignedNodeMB(alloc,false);
NodeRef node = createAlignedNodeMB(alloc,timesplit);
LBBox3fa bounds = empty;
for (size_t i=0; i<children.size(); i++) {
@@ -223,6 +248,9 @@ namespace embree
bounds.extend(child.lbounds);
}
if (timesplit)
bounds = current.prims.linearBounds(recalculatePrimRef);
return NodeRecordMB4D(node,bounds,current.prims.time_range);
}
@@ -231,10 +259,10 @@ namespace embree
{
/* variable to track the SAH of the best splitting approach */
float bestSAH = inf;
const float leafSAH = current.prims.leafSAH(cfg.logBlockSize);
const float leafSAH = current.prims.leafSAH(cfg.sahBlockSize);
/* perform standard binning in aligned space */
HeuristicBinning::Split alignedObjectSplit = alignedHeuristic.find(current.prims,cfg.logBlockSize);
HeuristicBinning::Split alignedObjectSplit = alignedHeuristic.find(current.prims,cfg.sahBlockSize);
float alignedObjectSAH = alignedObjectSplit.splitSAH();
bestSAH = min(alignedObjectSAH,bestSAH);
@@ -245,7 +273,7 @@ namespace embree
if (alignedObjectSAH > 0.7f*leafSAH) {
uspace = unalignedHeuristic.computeAlignedSpaceMB(scene,current.prims);
const SetMB sset = current.prims.primInfo(recalculatePrimRef,uspace);
unalignedObjectSplit = unalignedHeuristic.find(sset,cfg.logBlockSize,uspace);
unalignedObjectSplit = unalignedHeuristic.find(sset,cfg.sahBlockSize,uspace);
unalignedObjectSAH = 1.3f*unalignedObjectSplit.splitSAH(); // makes unaligned splits more expensive
bestSAH = min(unalignedObjectSAH,bestSAH);
}
@@ -255,7 +283,7 @@ namespace embree
typename HeuristicTemporal::Split temporal_split;
if (bestSAH > 0.5f*leafSAH) {
if (current.prims.time_range.size() > 1.01f/float(current.prims.max_num_time_segments)) {
temporal_split = temporalSplitHeuristic.find(current.prims,cfg.logBlockSize);
temporal_split = temporalSplitHeuristic.find(current.prims,cfg.sahBlockSize);
temporal_split_sah = temporal_split.splitSAH();
bestSAH = min(temporal_split_sah,bestSAH);
}
@@ -336,6 +364,13 @@ namespace embree
} while (children.size() < cfg.branchingFactor);
/* detect time_ranges that have shrunken */
for (size_t i=0; i<children.size(); i++) {
const BBox1f c = children[i].prims.time_range;
const BBox1f p = current.prims.time_range;
timesplit |= c.lower > p.lower || c.upper < p.upper;
}
/* create time split node */
if (timesplit)
{
+8 -8
View File
@@ -45,17 +45,17 @@ namespace embree
{
/*! default settings */
Settings ()
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
travCost(1.0f), intCost(1.0f), singleThreadThreshold(1024), primrefarrayalloc(inf) {}
/*! initialize settings from API settings */
Settings (const RTCBuildArguments& settings)
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
travCost(1.0f), intCost(1.0f), singleThreadThreshold(1024), primrefarrayalloc(inf)
{
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxBranchingFactor)) branchingFactor = settings.maxBranchingFactor;
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxDepth )) maxDepth = settings.maxDepth;
if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) logBlockSize = bsr(settings.sahBlockSize);
if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) sahBlockSize = settings.sahBlockSize;
if (RTC_BUILD_ARGUMENTS_HAS(settings,minLeafSize )) minLeafSize = settings.minLeafSize;
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxLeafSize )) maxLeafSize = settings.maxLeafSize;
if (RTC_BUILD_ARGUMENTS_HAS(settings,traversalCost )) travCost = settings.traversalCost;
@@ -63,13 +63,13 @@ namespace embree
}
Settings (size_t sahBlockSize, size_t minLeafSize, size_t maxLeafSize, float travCost, float intCost, size_t singleThreadThreshold, size_t primrefarrayalloc = inf)
: branchingFactor(2), maxDepth(32), logBlockSize(bsr(sahBlockSize)), minLeafSize(minLeafSize), maxLeafSize(maxLeafSize),
: branchingFactor(2), maxDepth(32), sahBlockSize(sahBlockSize), minLeafSize(minLeafSize), maxLeafSize(maxLeafSize),
travCost(travCost), intCost(intCost), singleThreadThreshold(singleThreadThreshold), primrefarrayalloc(primrefarrayalloc) {}
public:
size_t branchingFactor; //!< branching factor of BVH to build
size_t maxDepth; //!< maximum depth of BVH to build
size_t logBlockSize; //!< log2 of blocksize for SAH heuristic
size_t sahBlockSize; //!< blocksize for SAH heuristic
size_t minLeafSize; //!< minimum size of a leaf
size_t maxLeafSize; //!< maximum size of a leaf
float travCost; //!< estimated cost of one traversal step
@@ -213,10 +213,10 @@ namespace embree
progressMonitor(current.size());
/*! find best split */
auto split = heuristic.find(current.prims,cfg.logBlockSize);
auto split = heuristic.find(current.prims,cfg.sahBlockSize);
/*! compute leaf and split cost */
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.sahBlockSize);
const float splitSAH = cfg.travCost*halfArea(current.prims.geomBounds)+cfg.intCost*split.splitSAH();
assert((current.prims.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
@@ -260,7 +260,7 @@ namespace embree
BuildRecord& brecord = children[bestChild];
BuildRecord lrecord(current.depth+1);
BuildRecord rrecord(current.depth+1);
auto split = heuristic.find(brecord.prims,cfg.logBlockSize);
auto split = heuristic.find(brecord.prims,cfg.sahBlockSize);
heuristic.split(split,brecord.prims,lrecord.prims,rrecord.prims);
children[bestChild ] = lrecord;
children[numChildren] = rrecord;
+12 -8
View File
@@ -131,8 +131,10 @@ namespace embree
enum
{
SPLIT_OBJECT = 0,
SPLIT_TEMPORAL = 1,
SPLIT_FALLBACK = 2,
SPLIT_FALLBACK = 1,
SPLIT_ENFORCE = 2, // splits with larger ID are enforced in createLargeLeaf even if we could create a leaf already
SPLIT_TEMPORAL = 2,
SPLIT_GEOMID = 3,
};
/*! construct an invalid split by default */
@@ -348,7 +350,7 @@ namespace embree
}
/*! finds the best split by scanning binning information */
__forceinline Split best(const BinMapping<BINS>& mapping, const size_t blocks_shift) const
__forceinline Split best(const BinMapping<BINS>& mapping, const size_t sahBlockSize) const
{
/* sweep from right to left and compute parallel prefix of merged bounds */
vfloat4 rAreas[BINS];
@@ -364,7 +366,7 @@ namespace embree
rAreas[i][3] = 0.0f;
}
/* sweep from left to right and compute SAH */
vuint4 blocks_add = (1 << blocks_shift)-1;
vuint4 blocks_add = sahBlockSize-1;
vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0;
count = 0; bx = empty; by = empty; bz = empty;
for (size_t i=1; i<mapping.size(); i++, ii+=1)
@@ -375,8 +377,8 @@ namespace embree
bz.extend(bounds(i-1,2)); float Az = expectedApproxHalfArea(bz);
const vfloat4 lArea = vfloat4(Ax,Ay,Az,Az);
const vfloat4 rArea = rAreas[i];
const vuint4 lCount = (count +blocks_add) >> (unsigned int)(blocks_shift); // if blocks_shift >=1 then lCount < 4B and could be represented with an vint4, which would allow for faster vfloat4 conversions.
const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift);
const vuint4 lCount = (count +blocks_add) / vuint4(sahBlockSize); // if blocks_shift >=1 then lCount < 4B and could be represented with an vint4, which would allow for faster vfloat4 conversions.
const vuint4 rCount = (rCounts[i]+blocks_add) / vuint4(sahBlockSize);
const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount));
//const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount)));
@@ -456,7 +458,7 @@ namespace embree
vuint4 _counts[BINS]; //!< counts number of primitives that map into the bins
};
#if defined(__AVX512ER__) // KNL
#if 0 && defined(__AVX512ER__) // KNL
/*! mapping into bins */
template<>
@@ -829,8 +831,10 @@ namespace embree
}
/*! finds the best split by scanning binning information */
__forceinline Split best(const BinMapping<16>& mapping, const size_t blocks_shift) const
__forceinline Split best(const BinMapping<16>& mapping, const size_t sahBlockSize) const
{
const size_t blocks_shift = bsr(sahBlockSize);
/* find best dimension */
float bestSAH = inf;
int bestDim = -1;
@@ -40,8 +40,8 @@ namespace embree
return expectedApproxHalfArea(geomBounds)*float(size());
}
__forceinline float leafSAH(size_t block_shift) const {
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
__forceinline float leafSAH(size_t sahBlockSize) const {
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
}
};
@@ -70,21 +70,21 @@ namespace embree
: prims(prims) {}
/*! finds the best split */
__noinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize)
__noinline const Split find(const PrimInfoRange& pinfo, const size_t sahBlockSize)
{
if (likely(pinfo.size() < PARALLEL_THRESHOLD))
return find_template<false>(pinfo,logBlockSize);
return find_template<false>(pinfo,sahBlockSize);
else
return find_template<true>(pinfo,logBlockSize);
return find_template<true>(pinfo,sahBlockSize);
}
template<bool parallel>
__forceinline const Split find_template(const PrimInfoRange& pinfo, const size_t logBlockSize)
__forceinline const Split find_template(const PrimInfoRange& pinfo, const size_t sahBlockSize)
{
Binner binner(empty);
const BinMapping<BINS> mapping(pinfo);
bin_serial_or_parallel<parallel>(binner,prims,pinfo.begin(),pinfo.end(),PARALLEL_FIND_BLOCK_SIZE,mapping);
return binner.best(mapping,logBlockSize);
return binner.best(mapping,sahBlockSize);
}
/*! array partitioning */
@@ -186,12 +186,12 @@ namespace embree
static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128;
/*! finds the best split */
const Split find(const SetMB& set, const size_t logBlockSize)
const Split find(const SetMB& set, const size_t sahBlockSize)
{
ObjectBinner binner(empty);
const BinMapping<BINS> mapping(set.size(),set.centBounds);
bin_parallel(binner,set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping);
Split osplit = binner.best(mapping,logBlockSize);
bin_parallel(binner,set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping);
Split osplit = binner.best(mapping,sahBlockSize);
osplit.sah *= set.time_range.size();
if (!osplit.valid()) osplit.data = Split::SPLIT_FALLBACK; // use fallback split
return osplit;
@@ -200,8 +200,8 @@ namespace embree
/*! array partitioning */
__forceinline void split(const Split& split, const SetMB& set, SetMB& lset, SetMB& rset)
{
const size_t begin = set.object_range.begin();
const size_t end = set.object_range.end();
const size_t begin = set.begin();
const size_t end = set.end();
PrimInfoMB left = empty;
PrimInfoMB right = empty;
const vint4 vSplitPos(split.pos);
@@ -104,23 +104,23 @@ namespace embree
};
/*! finds the best split */
__forceinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize, const LinearSpace3fa& space)
__forceinline const Split find(const PrimInfoRange& pinfo, const size_t sahBlockSize, const LinearSpace3fa& space)
{
if (likely(pinfo.size() < 10000))
return find_template<false>(pinfo,logBlockSize,space);
return find_template<false>(pinfo,sahBlockSize,space);
else
return find_template<true>(pinfo,logBlockSize,space);
return find_template<true>(pinfo,sahBlockSize,space);
}
/*! finds the best split */
template<bool parallel>
const Split find_template(const PrimInfoRange& set, const size_t logBlockSize, const LinearSpace3fa& space)
const Split find_template(const PrimInfoRange& set, const size_t sahBlockSize, const LinearSpace3fa& space)
{
Binner binner(empty);
const BinMapping<BINS> mapping(set);
BinBoundsAndCenter binBoundsAndCenter(scene,space);
bin_serial_or_parallel<parallel>(binner,prims,set.begin(),set.end(),size_t(4096),mapping,binBoundsAndCenter);
return binner.best(mapping,logBlockSize);
return binner.best(mapping,sahBlockSize);
}
/*! array partitioning */
@@ -216,7 +216,7 @@ namespace embree
uint64_t bestGeomPrimID = -1;
/*! find curve with minimum ID that defines valid direction */
for (size_t i=set.object_range.begin(); i<set.object_range.end(); i++)
for (size_t i=set.begin(); i<set.end(); i++)
{
const PrimRefMB& prim = (*set.prims)[i];
const unsigned int geomID = prim.geomID();
@@ -225,8 +225,7 @@ namespace embree
if (geomprimID >= bestGeomPrimID) continue;
const Geometry* mesh = scene->get(geomID);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(set.time_range, (float)num_time_segments);
const range<int> tbounds = mesh->timeSegmentRange(set.time_range);
if (tbounds.size() == 0) continue;
const size_t t = (tbounds.begin()+tbounds.end())/2;
@@ -279,13 +278,13 @@ namespace embree
};
/*! finds the best split */
const Split find(const SetMB& set, const size_t logBlockSize, const LinearSpace3fa& space)
const Split find(const SetMB& set, const size_t sahBlockSize, const LinearSpace3fa& space)
{
BinBoundsAndCenter binBoundsAndCenter(scene,set.time_range,space);
ObjectBinner binner(empty);
const BinMapping<BINS> mapping(set.size(),set.centBounds);
bin_parallel(binner,set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping,binBoundsAndCenter);
Split osplit = binner.best(mapping,logBlockSize);
bin_parallel(binner,set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping,binBoundsAndCenter);
Split osplit = binner.best(mapping,sahBlockSize);
osplit.sah *= set.time_range.size();
if (!osplit.valid()) osplit.data = Split::SPLIT_FALLBACK; // use fallback split
return osplit;
@@ -295,8 +294,8 @@ namespace embree
__forceinline void split(const Split& split, const LinearSpace3fa& space, const SetMB& set, SetMB& lset, SetMB& rset)
{
BinBoundsAndCenter binBoundsAndCenter(scene,set.time_range,space);
const size_t begin = set.object_range.begin();
const size_t end = set.object_range.end();
const size_t begin = set.begin();
const size_t end = set.end();
PrimInfoMB left = empty;
PrimInfoMB right = empty;
const vint4 vSplitPos(split.pos);
+9 -9
View File
@@ -246,7 +246,7 @@ namespace embree
}
}
__noinline const Split find(PrimInfoExtRange& set, const size_t logBlockSize)
__noinline const Split find(PrimInfoExtRange& set, const size_t sahBlockSize)
{
/* single element */
if (set.size() <= 1)
@@ -294,28 +294,28 @@ namespace embree
}
/* find best split */
return object_find(set,logBlockSize);
return object_find(set,sahBlockSize);
}
/*! finds the best object split */
__forceinline const Split object_find(const PrimInfoExtRange& set,const size_t logBlockSize)
__forceinline const Split object_find(const PrimInfoExtRange& set,const size_t sahBlockSize)
{
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,logBlockSize);
else return parallel_object_find (set,logBlockSize);
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,sahBlockSize);
else return parallel_object_find (set,sahBlockSize);
}
/*! finds the best object split */
__noinline const Split sequential_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
__noinline const Split sequential_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
Binner binner(empty);
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
binner.bin(prims0,set.begin(),set.end(),mapping);
return binner.best(mapping,logBlockSize);
return binner.best(mapping,sahBlockSize);
}
/*! finds the best split */
__noinline const Split parallel_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
__noinline const Split parallel_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
Binner binner(empty);
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
@@ -327,7 +327,7 @@ namespace embree
Binner r = b0; r.merge(b1,_mapping.size()); return r;
};
binner = parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,binner,body,reduction);
return binner.best(mapping,logBlockSize);
return binner.best(mapping,sahBlockSize);
}
/*! array partitioning */
+4 -4
View File
@@ -344,7 +344,7 @@ namespace embree
}
/*! finds the best split by scanning binning information */
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t blocks_shift) const
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t sahBlockSize) const
{
/* sweep from right to left and compute parallel prefix of merged bounds */
vfloat4 rAreas[BINS];
@@ -361,7 +361,7 @@ namespace embree
}
/* sweep from left to right and compute SAH */
vuint4 blocks_add = (1 << blocks_shift)-1;
vuint4 blocks_add = sahBlockSize-1;
vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0; vuint4 vbestlCount = 0; vuint4 vbestrCount = 0;
count = 0; bx = empty; by = empty; bz = empty;
for (size_t i=1; i<BINS; i++, ii+=1)
@@ -372,8 +372,8 @@ namespace embree
bz.extend(bounds[i-1][2]); float Az = halfArea(bz);
const vfloat4 lArea = vfloat4(Ax,Ay,Az,Az);
const vfloat4 rArea = rAreas[i];
const vuint4 lCount = (count +blocks_add) >> (unsigned int)(blocks_shift);
const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift);
const vuint4 lCount = (count +blocks_add) / vuint4(sahBlockSize);
const vuint4 rCount = (rCounts[i]+blocks_add) / vuint4(sahBlockSize);
const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount));
// const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount)));
const vbool4 mask = sah < vbestSAH;
+19 -19
View File
@@ -48,8 +48,8 @@ namespace embree
return expectedApproxHalfArea(geomBounds)*float(size());
}
__forceinline float leafSAH(size_t block_shift) const {
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
__forceinline float leafSAH(size_t sahBlockSize) const {
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
}
};
@@ -186,10 +186,10 @@ namespace embree
}
/*! finds the best split */
const Split find(const PrimInfoExtRange& set, const size_t logBlockSize)
const Split find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
SplitInfo oinfo;
const ObjectSplit object_split = object_find(set,logBlockSize,oinfo);
const ObjectSplit object_split = object_find(set,sahBlockSize,oinfo);
const float object_split_sah = object_split.splitSAH();
if (unlikely(set.has_ext_range()))
@@ -200,7 +200,7 @@ namespace embree
if (safeArea(overlap) >= SPATIAL_ASPLIT_AREA_THRESHOLD*safeArea(root_info.geomBounds) &&
safeArea(overlap) >= SPATIAL_ASPLIT_OVERLAP_THRESHOLD*safeArea(set.geomBounds))
{
const SpatialSplit spatial_split = spatial_find(set, logBlockSize);
const SpatialSplit spatial_split = spatial_find(set, sahBlockSize);
const float spatial_split_sah = spatial_split.splitSAH();
/* valid spatial split, better SAH and number of splits do not exceed extended range */
@@ -216,25 +216,25 @@ namespace embree
}
/*! finds the best object split */
__forceinline const ObjectSplit object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
__forceinline const ObjectSplit object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
{
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,logBlockSize,info);
else return parallel_object_find (set,logBlockSize,info);
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,sahBlockSize,info);
else return parallel_object_find (set,sahBlockSize,info);
}
/*! finds the best object split */
__noinline const ObjectSplit sequential_object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
__noinline const ObjectSplit sequential_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
{
ObjectBinner binner(empty);
const BinMapping<OBJECT_BINS> mapping(set);
binner.bin(prims0,set.begin(),set.end(),mapping);
ObjectSplit s = binner.best(mapping,logBlockSize);
ObjectSplit s = binner.best(mapping,sahBlockSize);
binner.getSplitInfo(mapping, s, info);
return s;
}
/*! finds the best split */
__noinline const ObjectSplit parallel_object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
__noinline const ObjectSplit parallel_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
{
ObjectBinner binner(empty);
const BinMapping<OBJECT_BINS> mapping(set);
@@ -242,29 +242,29 @@ namespace embree
binner = parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,binner,
[&] (const range<size_t>& r) -> ObjectBinner { ObjectBinner binner(empty); binner.bin(prims0+r.begin(),r.size(),_mapping); return binner; },
[&] (const ObjectBinner& b0, const ObjectBinner& b1) -> ObjectBinner { ObjectBinner r = b0; r.merge(b1,_mapping.size()); return r; });
ObjectSplit s = binner.best(mapping,logBlockSize);
ObjectSplit s = binner.best(mapping,sahBlockSize);
binner.getSplitInfo(mapping, s, info);
return s;
}
/*! finds the best spatial split */
__forceinline const SpatialSplit spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
__forceinline const SpatialSplit spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
if (set.size() < PARALLEL_THRESHOLD) return sequential_spatial_find(set, logBlockSize);
else return parallel_spatial_find (set, logBlockSize);
if (set.size() < PARALLEL_THRESHOLD) return sequential_spatial_find(set, sahBlockSize);
else return parallel_spatial_find (set, sahBlockSize);
}
/*! finds the best spatial split */
__noinline const SpatialSplit sequential_spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
__noinline const SpatialSplit sequential_spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
SpatialBinner binner(empty);
const SpatialBinMapping<SPATIAL_BINS> mapping(set);
binner.bin2(splitterFactory,prims0,set.begin(),set.end(),mapping);
/* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/
return binner.best(mapping,logBlockSize); //,set.ext_size());
return binner.best(mapping,sahBlockSize); //,set.ext_size());
}
__noinline const SpatialSplit parallel_spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
__noinline const SpatialSplit parallel_spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
{
SpatialBinner binner(empty);
const SpatialBinMapping<SPATIAL_BINS> mapping(set);
@@ -276,7 +276,7 @@ namespace embree
return binner; },
[&] (const SpatialBinner& b0, const SpatialBinner& b1) -> SpatialBinner { return SpatialBinner::reduce(b0,b1); });
/* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/
return binner.best(mapping,logBlockSize); //,set.ext_size());
return binner.best(mapping,sahBlockSize); //,set.ext_size());
}
+3 -3
View File
@@ -75,7 +75,7 @@ namespace embree
}
/*! finds the best split */
const Split find(const range<size_t>& set, size_t logBlockSize)
const Split find(const range<size_t>& set, size_t sahBlockSize)
{
Vec3fa axis0(0,0,1);
uint64_t bestGeomPrimID = -1;
@@ -132,8 +132,8 @@ namespace embree
return Split(inf,axis0,axis1);
/*! calculate sah for the split */
const size_t lblocks = (lnum+(1ull<<logBlockSize)-1ull) >> logBlockSize;
const size_t rblocks = (rnum+(1ull<<logBlockSize)-1ull) >> logBlockSize;
const size_t lblocks = (lnum+sahBlockSize-1ull) / sahBlockSize;
const size_t rblocks = (rnum+sahBlockSize-1ull) / sahBlockSize;
const float sah = madd(float(lblocks),halfArea(lbounds),float(rblocks)*halfArea(rbounds));
return Split(sah,axis0,axis1);
}
+74 -37
View File
@@ -17,6 +17,7 @@
#pragma once
#include "../common/primref_mb.h"
#include "../../common/algorithms/parallel_filter.h"
#define MBLUR_TIME_SPLIT_THRESHOLD 1.25f
@@ -53,13 +54,13 @@ namespace embree
}
}
void bin(const PrimRefMB* prims, size_t begin, size_t end, BBox1f time_range, size_t numTimeSegments, const RecalculatePrimRef& recalculatePrimRef)
void bin(const PrimRefMB* prims, size_t begin, size_t end, BBox1f time_range, const SetMB& set, const RecalculatePrimRef& recalculatePrimRef)
{
for (int b=0; b<BINS-1; b++)
{
const float t = float(b+1)/float(BINS);
const float ct = lerp(time_range.lower,time_range.upper,t);
const float center_time = roundf(ct * float(numTimeSegments)) / float(numTimeSegments);
const float center_time = set.align_time(ct);
if (center_time <= time_range.lower) continue;
if (center_time >= time_range.upper) continue;
const BBox1f dt0(time_range.lower,center_time);
@@ -68,30 +69,40 @@ namespace embree
/* find linear bounds for both time segments */
for (size_t i=begin; i<end; i++)
{
const LBBox3fa bn0 = recalculatePrimRef.linearBounds(prims[i],dt0);
const LBBox3fa bn1 = recalculatePrimRef.linearBounds(prims[i],dt1);
if (prims[i].time_range_overlap(dt0))
{
const LBBox3fa bn0 = recalculatePrimRef.linearBounds(prims[i],dt0);
#if MBLUR_BIN_LBBOX
bounds0[b].extend(bn0);
bounds1[b].extend(bn1);
bounds0[b].extend(bn0);
#else
bounds0[b].extend(bn0.interpolate(0.5f));
bounds1[b].extend(bn1.interpolate(0.5f));
bounds0[b].extend(bn0.interpolate(0.5f));
#endif
count0[b] += getTimeSegmentRange(dt0,(float)prims[i].totalTimeSegments()).size();
count1[b] += getTimeSegmentRange(dt1,(float)prims[i].totalTimeSegments()).size();
count0[b] += prims[i].timeSegmentRange(dt0).size();
}
if (prims[i].time_range_overlap(dt1))
{
const LBBox3fa bn1 = recalculatePrimRef.linearBounds(prims[i],dt1);
#if MBLUR_BIN_LBBOX
bounds1[b].extend(bn1);
#else
bounds1[b].extend(bn1.interpolate(0.5f));
#endif
count1[b] += prims[i].timeSegmentRange(dt1).size();
}
}
}
}
__forceinline void bin_parallel(const PrimRefMB* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, BBox1f time_range, size_t numTimeSegments, const RecalculatePrimRef& recalculatePrimRef)
__forceinline void bin_parallel(const PrimRefMB* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, BBox1f time_range, const SetMB& set, const RecalculatePrimRef& recalculatePrimRef)
{
if (likely(end-begin < parallelThreshold)) {
bin(prims,begin,end,time_range,numTimeSegments,recalculatePrimRef);
bin(prims,begin,end,time_range,set,recalculatePrimRef);
}
else
{
auto bin = [&](const range<size_t>& r) -> TemporalBinInfo {
TemporalBinInfo binner(empty); binner.bin(prims, r.begin(), r.end(), time_range, numTimeSegments, recalculatePrimRef); return binner;
TemporalBinInfo binner(empty); binner.bin(prims, r.begin(), r.end(), time_range, set, recalculatePrimRef); return binner;
};
*this = parallel_reduce(begin,end,blockSize,TemporalBinInfo(empty),bin,merge2);
}
@@ -113,7 +124,7 @@ namespace embree
TemporalBinInfo r = a; r.merge(b); return r;
}
Split best(int logBlockSize, BBox1f time_range, size_t numTimeSegments)
Split best(int sahBlockSize, BBox1f time_range, const SetMB& set)
{
float bestSAH = inf;
float bestPos = 0.0f;
@@ -121,17 +132,19 @@ namespace embree
{
float t = float(b+1)/float(BINS);
float ct = lerp(time_range.lower,time_range.upper,t);
const float center_time = roundf(ct * float(numTimeSegments)) / float(numTimeSegments);
const float center_time = set.align_time(ct);
if (center_time <= time_range.lower) continue;
if (center_time >= time_range.upper) continue;
const BBox1f dt0(time_range.lower,center_time);
const BBox1f dt1(center_time,time_range.upper);
/* calculate sah */
const size_t lCount = (count0[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
const size_t rCount = (count1[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
const float sah0 = expectedApproxHalfArea(bounds0[b])*float(lCount)*dt0.size();
const float sah1 = expectedApproxHalfArea(bounds1[b])*float(rCount)*dt1.size();
const size_t lCount = (count0[b]+sahBlockSize-1) / sahBlockSize;
const size_t rCount = (count1[b]+sahBlockSize-1) / sahBlockSize;
float sah0 = expectedApproxHalfArea(bounds0[b])*float(lCount)*dt0.size();
float sah1 = expectedApproxHalfArea(bounds1[b])*float(rCount)*dt1.size();
if (unlikely(lCount == 0)) sah0 = 0.0f; // happens for initial splits when objects not alive over entire shutter time
if (unlikely(rCount == 0)) sah1 = 0.0f;
const float sah = sah0+sah1;
if (sah < bestSAH) {
bestSAH = sah;
@@ -150,13 +163,12 @@ namespace embree
};
/*! finds the best split */
const Split find(const SetMB& set, const size_t logBlockSize)
const Split find(const SetMB& set, const size_t sahBlockSize)
{
assert(set.object_range.size() > 0);
unsigned numTimeSegments = unsigned(set.max_num_time_segments);
assert(set.size() > 0);
TemporalBinInfo binner(empty);
binner.bin_parallel(set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,set.time_range,numTimeSegments,recalculatePrimRef);
Split tsplit = binner.best((int)logBlockSize,set.time_range,numTimeSegments);
binner.bin_parallel(set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,set.time_range,set,recalculatePrimRef);
Split tsplit = binner.best((int)sahBlockSize,set.time_range,set);
if (!tsplit.valid()) tsplit.data = Split::SPLIT_FALLBACK; // use fallback split
return tsplit;
}
@@ -169,35 +181,60 @@ namespace embree
mvector<PrimRefMB>& prims = *set.prims;
/* calculate primrefs for first time range */
std::unique_ptr<mvector<PrimRefMB>> new_vector(new mvector<PrimRefMB>(device, set.object_range.size()));
std::unique_ptr<mvector<PrimRefMB>> new_vector(new mvector<PrimRefMB>(device, set.size()));
PrimRefVector lprims = new_vector.get();
auto reduction_func0 = [&] ( const range<size_t>& r) {
auto reduction_func0 = [&] (const range<size_t>& r) {
PrimInfoMB pinfo = empty;
for (size_t i=r.begin(); i<r.end(); i++)
{
const PrimRefMB& prim = recalculatePrimRef(prims[i],time_range0);
(*lprims)[i-set.object_range.begin()] = prim;
pinfo.add_primref(prim);
if (likely(prims[i].time_range_overlap(time_range0)))
{
const PrimRefMB& prim = recalculatePrimRef(prims[i],time_range0);
(*lprims)[i-set.begin()] = prim;
pinfo.add_primref(prim);
}
else
{
(*lprims)[i-set.begin()] = prims[i];
}
}
return pinfo;
};
const PrimInfoMB linfo = parallel_reduce(set.object_range,PARALLEL_PARTITION_BLOCK_SIZE,PARALLEL_THRESHOLD,PrimInfoMB(empty),reduction_func0,PrimInfoMB::merge2);
PrimInfoMB linfo = parallel_reduce(set.object_range,PARALLEL_PARTITION_BLOCK_SIZE,PARALLEL_THRESHOLD,PrimInfoMB(empty),reduction_func0,PrimInfoMB::merge2);
/* primrefs for first time range are in lprims[0 .. set.size()) */
/* some primitives may need to be filtered out */
if (linfo.size() != set.size())
linfo.object_range._end = parallel_filter(lprims->data(), size_t(0), set.size(), size_t(1024),
[&](const PrimRefMB& prim) { return prim.time_range_overlap(time_range0); });
lset = SetMB(linfo,lprims,time_range0);
/* calculate primrefs for second time range */
auto reduction_func1 = [&] ( const range<size_t>& r) {
auto reduction_func1 = [&] (const range<size_t>& r) {
PrimInfoMB pinfo = empty;
for (size_t i=r.begin(); i<r.end(); i++)
{
const PrimRefMB& prim = recalculatePrimRef(prims[i],time_range1);
prims[i] = prim;
pinfo.add_primref(prim);
if (likely(prims[i].time_range_overlap(time_range1)))
{
const PrimRefMB& prim = recalculatePrimRef(prims[i],time_range1);
prims[i] = prim;
pinfo.add_primref(prim);
}
}
return pinfo;
};
const PrimInfoMB rinfo = parallel_reduce(set.object_range,PARALLEL_PARTITION_BLOCK_SIZE,PARALLEL_THRESHOLD,PrimInfoMB(empty),reduction_func1,PrimInfoMB::merge2);
rset = SetMB(rinfo,&prims,set.object_range,time_range1);
PrimInfoMB rinfo = parallel_reduce(set.object_range,PARALLEL_PARTITION_BLOCK_SIZE,PARALLEL_THRESHOLD,PrimInfoMB(empty),reduction_func1,PrimInfoMB::merge2);
rinfo.object_range = range<size_t>(set.begin(), set.begin() + rinfo.size());
/* primrefs for second time range are in prims[set.begin() .. set.end()) */
/* some primitives may need to be filtered out */
if (rinfo.size() != set.size())
rinfo.object_range._end = parallel_filter(prims.data(), set.begin(), set.end(), size_t(1024),
[&](const PrimRefMB& prim) { return prim.time_range_overlap(time_range1); });
rset = SetMB(rinfo,&prims,time_range1);
return new_vector;
}
+40 -16
View File
@@ -145,8 +145,8 @@ namespace embree
//return halfArea(geomBounds)*blocks(num);
}
__forceinline float leafSAH(size_t block_shift) const {
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
__forceinline float leafSAH(size_t sahBlockSize) const {
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
//return halfArea(geomBounds)*float((num+3) >> 2);
//return halfArea(geomBounds)*blocks(num);
}
@@ -175,32 +175,48 @@ namespace embree
}
__forceinline PrimInfoMBT (EmptyTy)
: CentGeom<BBox>(empty), object_range(0,0), num_time_segments(0), max_num_time_segments(0), time_range(0.0f,1.0f) {}
: CentGeom<BBox>(empty), object_range(0,0), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}
__forceinline PrimInfoMBT (size_t begin, size_t end)
: CentGeom<BBox>(empty), object_range(begin,end), num_time_segments(0), max_num_time_segments(0), time_range(0.0f,1.0f) {}
: CentGeom<BBox>(empty), object_range(begin,end), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}
template<typename PrimRef>
__forceinline void add_primref(const PrimRef& prim)
{
CentGeom<BBox>::extend_primref(prim);
time_range.extend(prim.time_range);
object_range._end++;
num_time_segments += prim.size();
max_num_time_segments = max(max_num_time_segments,size_t(prim.totalTimeSegments()));
if (max_num_time_segments < prim.totalTimeSegments()) {
max_num_time_segments = prim.totalTimeSegments();
max_time_range = prim.time_range;
}
}
__forceinline void merge(const PrimInfoMBT& other)
{
CentGeom<BBox>::merge(other);
time_range.extend(other.time_range);
object_range._begin += other.object_range.begin();
object_range._end += other.object_range.end();
object_range._end += other.object_range.end();
num_time_segments += other.num_time_segments;
max_num_time_segments = max(max_num_time_segments,other.max_num_time_segments);
if (max_num_time_segments < other.max_num_time_segments) {
max_num_time_segments = other.max_num_time_segments;
max_time_range = other.max_time_range;
}
}
static __forceinline const PrimInfoMBT merge2(const PrimInfoMBT& a, const PrimInfoMBT& b) {
PrimInfoMBT r = a; r.merge(b); return r;
}
__forceinline size_t begin() const {
return object_range.begin();
}
__forceinline size_t end() const {
return object_range.end();
}
/*! returns the number of primitives */
__forceinline size_t size() const {
@@ -215,8 +231,16 @@ namespace embree
return time_range.size()*expectedApproxHalfArea(geomBounds)*float(num_time_segments);
}
__forceinline float leafSAH(size_t block_shift) const {
return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+(size_t(1)<<block_shift)-1) >> block_shift);
__forceinline float leafSAH(size_t sahBlockSize) const {
return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+sahBlockSize-1) / sahBlockSize);
}
__forceinline float align_time(float ct) const
{
//return roundf(ct * float(numTimeSegments)) / float(numTimeSegments);
float t0 = (ct-max_time_range.lower)/max_time_range.size();
float t1 = roundf(t0 * float(max_num_time_segments)) / float(max_num_time_segments);
return t1*max_time_range.size()+max_time_range.lower;
}
/*! stream output */
@@ -235,7 +259,8 @@ namespace embree
range<size_t> object_range; //!< primitive range
size_t num_time_segments; //!< total number of time segments of all added primrefs
size_t max_num_time_segments; //!< maximum number of time segments of a primitive
BBox1f time_range;
BBox1f max_time_range; //!< time range of primitive with max_num_time_segments
BBox1f time_range; //!< merged time range of primitives when merging prims, or additionally clipped with build time range when used in SetMB
};
typedef PrimInfoMBT<typename PrimRefMB::BBox> PrimInfoMB;
@@ -250,21 +275,20 @@ namespace embree
__forceinline SetMB() {}
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims)
: PrimInfoMB(pinfo_i), prims(prims) {}
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims)
: PrimInfoMB(pinfo_i), prims(prims) {}
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, range<size_t> object_range_in, BBox1f time_range_in) // FIXME: remove
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, range<size_t> object_range_in, BBox1f time_range_in)
: PrimInfoMB(pinfo_i), prims(prims)
{
object_range = object_range_in;
time_range = time_range_in;
time_range = intersect(time_range,time_range_in);
}
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, BBox1f time_range_in)
: PrimInfoMB(pinfo_i), prims(prims)
{
object_range = range<size_t>(0,prims->size());
time_range = time_range_in;
time_range = intersect(time_range,time_range_in);
}
void deterministic_order() const
+2
View File
@@ -110,6 +110,8 @@ namespace embree
return mesh->createPrimRefMBArray(prims,t0t1,r,base.size());
}, [](const PrimInfoMB& a, const PrimInfoMB& b) -> PrimInfoMB { return PrimInfoMB::merge2(a,b); });
}
/* the BVH starts with that time range, even though primitives might have smaller/larger time range */
pinfo.time_range = t0t1;
return pinfo;
}
+1 -1
View File
@@ -69,7 +69,7 @@ namespace embree
/* builder settings */
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = bsf(CurvePrimitive::max_size());
settings.sahBlockSize = CurvePrimitive::max_size();
settings.minLeafSize = CurvePrimitive::max_size();
settings.maxLeafSize = CurvePrimitive::max_size();
settings.finished_range_threshold = numPrimitives/1000;
+2 -2
View File
@@ -66,7 +66,7 @@ namespace embree
BVHBuilderHairMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = bsf(CurvePrimitive::max_size());
settings.sahBlockSize = CurvePrimitive::max_size();
settings.minLeafSize = CurvePrimitive::max_size();
settings.maxLeafSize = CurvePrimitive::max_size();
@@ -76,7 +76,7 @@ namespace embree
if (prims.size() == 0)
return NodeRecordMB4D(BVH::emptyNode,empty,empty);
const unsigned int geomID0 = (*prims.prims)[prims.object_range.begin()].geomID();
const unsigned int geomID0 = (*prims.prims)[prims.begin()].geomID();
if (scene->get(geomID0)->getCurveBasis() == Geometry::GTY_BASIS_LINEAR)
return LinePrimitive::createLeafMB(bvh,prims,alloc);
else
+39 -30
View File
@@ -44,6 +44,7 @@ namespace embree
namespace isa
{
#if 0
template<int N, typename Primitive>
struct CreateMBlurLeaf
{
@@ -57,6 +58,7 @@ namespace embree
{
size_t items = Primitive::blocks(set.size());
size_t start = set.begin();
for (size_t i=start; i<end; i++) assert((*current.prims.prims)[start].geomID() == (*current.prims.prims)[i].geomID()); // assert that all geomIDs are identical
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
NodeRef node = bvh->encodeLeaf((char*)accel,items);
@@ -71,7 +73,7 @@ namespace embree
PrimRef* prims;
size_t time;
};
#endif
template<int N, typename Mesh, typename Primitive>
struct CreateMSMBlurLeaf
@@ -84,13 +86,15 @@ namespace embree
__forceinline const NodeRecordMB4D operator() (const BVHBuilderMSMBlur::BuildRecord& current, const FastAllocator::CachedAllocator& alloc) const
{
size_t items = Primitive::blocks(current.prims.object_range.size());
size_t start = current.prims.object_range.begin();
size_t items = Primitive::blocks(current.prims.size());
size_t start = current.prims.begin();
size_t end = current.prims.end();
for (size_t i=start; i<end; i++) assert((*current.prims.prims)[start].geomID() == (*current.prims.prims)[i].geomID()); // assert that all geomIDs are identical
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteNodeAlignment);
NodeRef node = bvh->encodeLeaf((char*)accel,items);
LBBox3fa allBounds = empty;
for (size_t i=0; i<items; i++)
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range));
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.end(), bvh->scene, current.prims.time_range));
return NodeRecordMB4D(node,allBounds,current.prims.time_range);
}
@@ -128,12 +132,12 @@ namespace embree
profile(2,PROFILE_RUNS,numPrimitives,[&] (ProfileTimer& timer) {
#endif
const size_t numTimeSteps = scene->getNumTimeSteps<Mesh,true>();
const size_t numTimeSegments = numTimeSteps-1; assert(numTimeSteps > 1);
//const size_t numTimeSteps = scene->getNumTimeSteps<Mesh,true>();
//const size_t numTimeSegments = numTimeSteps-1; assert(numTimeSteps > 1);
if (numTimeSegments == 1)
/*if (numTimeSegments == 1)
buildSingleSegment(numPrimitives);
else
else*/
buildMultiSegment(numPrimitives);
#if PROFILE
@@ -146,6 +150,7 @@ namespace embree
bvh->postBuild(t0);
}
#if 0 // No longer compatible when time_ranges are present for geometries. Would have to create temporal nodes sometimes, and put only a single geometry into leaf.
void buildSingleSegment(size_t numPrimitives)
{
/* create primref array */
@@ -162,7 +167,7 @@ namespace embree
GeneralBVHBuilder::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = bsr(sahBlockSize);
settings.sahBlockSize = sahBlockSize;
settings.minLeafSize = minLeafSize;
settings.maxLeafSize = maxLeafSize;
settings.travCost = travCost;
@@ -177,14 +182,16 @@ namespace embree
bvh->set(root.ref,root.lbounds,pinfo.size());
}
#endif
void buildMultiSegment(size_t numPrimitives)
{
/* create primref array */
mvector<PrimRefMB> prims(scene->device,numPrimitives);
PrimInfoMB pinfo = createPrimRefArrayMSMBlur(scene,Mesh::geom_type,prims,bvh->scene->progressInterface);
/* early out if no valid primitives */
if (pinfo.object_range.size() == 0) { bvh->clear(); return; }
if (pinfo.size() == 0) { bvh->clear(); return; }
/* estimate acceleration structure size */
const size_t node_bytes = pinfo.num_time_segments*sizeof(AlignedNodeMB)/(4*N);
@@ -195,7 +202,7 @@ namespace embree
BVHBuilderMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxDepth;
settings.logBlockSize = bsr(sahBlockSize);
settings.sahBlockSize = sahBlockSize;
settings.minLeafSize = minLeafSize;
settings.maxLeafSize = maxLeafSize;
settings.travCost = travCost;
@@ -245,8 +252,8 @@ namespace embree
const size_t y = subgrid.y();
const LBBox3fa lbounds = mesh->linearBounds(mesh->grid(primID),x,y,time_range);
const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, buildID);
const range<int> tbounds = mesh->timeSegmentRange(time_range);
return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, num_time_segments, geomID, buildID);
}
__forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const {
@@ -262,7 +269,6 @@ namespace embree
};
template<int N>
struct CreateMSMBlurLeafGrid
{
@@ -274,8 +280,8 @@ namespace embree
__forceinline const NodeRecordMB4D operator() (const BVHBuilderMSMBlur::BuildRecord& current, const FastAllocator::CachedAllocator& alloc) const
{
const size_t items = current.prims.object_range.size();
const size_t start = current.prims.object_range.begin();
const size_t items = current.prims.size();
const size_t start = current.prims.begin();
const PrimRefMB* prims = current.prims.prims->data();
/* collect all subsets with unique geomIDs */
@@ -336,6 +342,7 @@ namespace embree
const SubGridBuildData * const sgrids;
};
#if 0
template<int N>
struct CreateLeafGridMB
{
@@ -410,7 +417,7 @@ namespace embree
BVH* bvh;
const SubGridBuildData * const sgrids;
};
#endif
/* Motion blur BVH with 4D nodes and internal time splits */
@@ -503,7 +510,7 @@ namespace embree
PrimInfoMB pinfoMB(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!mesh->valid(j, getTimeSegmentRange(t0t1, mesh->fnumTimeSegments))) continue;
if (!mesh->valid(j, mesh->timeSegmentRange(t0t1))) continue;
LBBox3fa bounds(empty);
PrimInfoMB gridMB(0,mesh->getNumSubGrids(j));
pinfoMB.merge(gridMB);
@@ -524,13 +531,13 @@ namespace embree
PrimInfoMB pinfoMB(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!mesh->valid(j, getTimeSegmentRange(t0t1, mesh->fnumTimeSegments))) continue;
if (!mesh->valid(j, mesh->timeSegmentRange(t0t1))) continue;
const GridMesh::Grid &g = mesh->grid(j);
for (unsigned int y=0; y<g.resY-1u; y+=2)
for (unsigned int x=0; x<g.resX-1u; x+=2)
{
const PrimRefMB prim(mesh->linearBounds(g,x,y,t0t1),mesh->numTimeSegments(),mesh->numTimeSegments(),mesh->geomID,unsigned(p_index));
const PrimRefMB prim(mesh->linearBounds(g,x,y,t0t1),mesh->numTimeSegments(),mesh->time_range,mesh->numTimeSegments(),mesh->geomID,unsigned(p_index));
pinfoMB.add_primref(prim);
sgrids[p_index] = SubGridBuildData(x | g.get3x3FlagsX(x), y | g.get3x3FlagsY(y), unsigned(j));
prims[p_index++] = prim;
@@ -551,12 +558,12 @@ namespace embree
double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "BuilderMBlurSAHGrid");
const size_t numTimeSteps = scene->getNumTimeSteps<GridMesh,true>();
const size_t numTimeSegments = numTimeSteps-1; assert(numTimeSteps > 1);
if (numTimeSegments == 1)
buildSingleSegment(numPrimitives);
else
buildMultiSegment(numPrimitives);
//const size_t numTimeSteps = scene->getNumTimeSteps<GridMesh,true>();
//const size_t numTimeSegments = numTimeSteps-1; assert(numTimeSteps > 1);
//if (numTimeSegments == 1)
// buildSingleSegment(numPrimitives);
//else
buildMultiSegment(numPrimitives);
/* clear temporary data for static geometry */
if (scene->isStaticAccel()) bvh->shrink();
@@ -564,6 +571,7 @@ namespace embree
bvh->postBuild(t0);
}
#if 0
void buildSingleSegment(size_t numPrimitives)
{
/* create primref array */
@@ -582,7 +590,7 @@ namespace embree
GeneralBVHBuilder::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = bsr(sahBlockSize);
settings.sahBlockSize = sahBlockSize;
settings.minLeafSize = minLeafSize;
settings.maxLeafSize = maxLeafSize;
settings.travCost = travCost;
@@ -600,7 +608,8 @@ namespace embree
bvh->set(root.ref,root.lbounds,pinfo.size());
}
#endif
void buildMultiSegment(size_t numPrimitives)
{
/* create primref array */
@@ -608,7 +617,7 @@ namespace embree
PrimInfoMB pinfo = createPrimRefArrayMSMBlurGrid(scene,prims,bvh->scene->progressInterface);
/* early out if no valid primitives */
if (pinfo.object_range.size() == 0) { bvh->clear(); return; }
if (pinfo.size() == 0) { bvh->clear(); return; }
@@ -626,7 +635,7 @@ namespace embree
BVHBuilderMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxDepth;
settings.logBlockSize = bsr(sahBlockSize);
settings.sahBlockSize = sahBlockSize;
settings.minLeafSize = minLeafSize;
settings.maxLeafSize = maxLeafSize;
settings.travCost = travCost;
+16 -16
View File
@@ -171,7 +171,7 @@ namespace embree
/* settings for BVH build */
GeneralBVHBuilder::Settings settings;
settings.logBlockSize = bsr(N);
settings.sahBlockSize = N;
settings.minLeafSize = 1;
settings.maxLeafSize = 1;
settings.travCost = 1.0f;
@@ -208,19 +208,19 @@ namespace embree
__forceinline SubdivRecalculatePrimRef (mvector<BBox3fa>& bounds, SubdivPatch1* patches)
: bounds(bounds), patches(patches) {}
__forceinline PrimRefMB operator() (const size_t patchIndexMB, const unsigned num_time_segments, const BBox1f time_range) const
__forceinline PrimRefMB operator() (const size_t patchIndexMB, const BBox1f prim_time_range, const unsigned prim_num_time_segments, const BBox1f time_range) const
{
const LBBox3fa lbounds = LBBox3fa([&] (size_t itime) { return bounds[patchIndexMB+itime]; }, time_range, (float)num_time_segments);
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, patchIndexMB);
const LBBox3fa lbounds = LBBox3fa([&] (size_t itime) { return bounds[patchIndexMB+itime]; }, time_range, prim_time_range, (float)prim_num_time_segments);
const range<int> tbounds = getTimeSegmentRange(time_range, prim_time_range, (float)prim_num_time_segments);
return PrimRefMB (empty, lbounds, tbounds.size(), prim_time_range, prim_num_time_segments, patchIndexMB);
}
__forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range) const {
return operator()(prim.ID(),prim.totalTimeSegments(),time_range);
return operator()(prim.ID(),prim.time_range,prim.totalTimeSegments(),time_range);
}
__forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds[prim.ID()+itime]; }, time_range, (float)prim.totalTimeSegments());
return LBBox3fa([&] (size_t itime) { return bounds[prim.ID()+itime]; }, time_range, prim.time_range, (float)prim.totalTimeSegments());
}
};
@@ -263,10 +263,10 @@ namespace embree
sMB += count * mesh->numTimeSteps;
}
return PrimInfoMB(s,sMB);
}, [](const PrimInfoMB& a, const PrimInfoMB& b) -> PrimInfoMB { return PrimInfoMB(a.object_range.begin()+b.object_range.begin(),a.object_range.end()+b.object_range.end()); });
}, [](const PrimInfoMB& a, const PrimInfoMB& b) -> PrimInfoMB { return PrimInfoMB(a.begin()+b.begin(),a.end()+b.end()); });
numSubPatches = pinfo.object_range.begin();
numSubPatchesMB = pinfo.object_range.end();
numSubPatches = pinfo.begin();
numSubPatchesMB = pinfo.end();
}
void rebuild(size_t numPrimitives, ParallelForForPrefixSumState<PrimInfoMB>& pstate)
@@ -288,8 +288,8 @@ namespace embree
BVH_Allocator alloc(bvh);
patch_eval_subdivision(mesh->getHalfEdge(0,f),[&](const Vec2f uv[4], const int subdiv[4], const float edge_level[4], int subPatch)
{
const size_t patchIndex = base.object_range.begin()+s;
const size_t patchIndexMB = base.object_range.end()+sMB;
const size_t patchIndex = base.begin()+s;
const size_t patchIndexMB = base.end()+sMB;
assert(patchIndex < numPrimitives);
for (size_t t=0; t<mesh->numTimeSteps; t++)
@@ -299,7 +299,7 @@ namespace embree
}
SubdivPatch1Base& patch0 = subdiv_patches[patchIndexMB];
patch0.root_ref.set((int64_t) GridSOA::create(&patch0,(unsigned)mesh->numTimeSteps,scene,alloc,&bounds[patchIndexMB]));
primsMB[patchIndex] = recalculatePrimRef(patchIndexMB,mesh->numTimeSegments(),BBox1f(0.0f,1.0f));
primsMB[patchIndex] = recalculatePrimRef(patchIndexMB,mesh->time_range,mesh->numTimeSegments(),BBox1f(0.0f,1.0f));
s++;
sMB += mesh->numTimeSteps;
pinfo.add_primref(primsMB[patchIndex]);
@@ -309,14 +309,14 @@ namespace embree
pinfo.object_range._end = sMB;
return pinfo;
}, [](const PrimInfoMB& a, const PrimInfoMB& b) -> PrimInfoMB { return PrimInfoMB::merge2(a,b); });
pinfo.object_range._end = pinfo.object_range.begin();
pinfo.object_range._end = pinfo.begin();
pinfo.object_range._begin = 0;
auto createLeafFunc = [&] (const BVHBuilderMSMBlur::BuildRecord& current, const Allocator& alloc) -> NodeRecordMB4D {
mvector<PrimRefMB>& prims = *current.prims.prims;
size_t items MAYBE_UNUSED = current.prims.size();
assert(items == 1);
const size_t patchIndexMB = prims[current.prims.object_range.begin()].ID();
const size_t patchIndexMB = prims[current.prims.begin()].ID();
SubdivPatch1Base& patch = subdiv_patches[patchIndexMB+0];
NodeRef node = bvh->encodeLeaf((char*)&patch,1);
size_t patchNumTimeSteps = scene->get<SubdivMesh>(patch.geomID())->numTimeSteps;
@@ -328,7 +328,7 @@ namespace embree
BVHBuilderMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxDepth;
settings.logBlockSize = bsr(N);
settings.sahBlockSize = N;
settings.minLeafSize = 1;
settings.maxLeafSize = 1;
settings.travCost = 1.0f;
+2 -2
View File
@@ -212,7 +212,7 @@ namespace embree
GeneralBVHBuilder::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = bsr(N);
settings.sahBlockSize = N;
settings.minLeafSize = 1;
settings.maxLeafSize = 1;
settings.travCost = 1.0f;
@@ -308,7 +308,7 @@ namespace embree
#endif
std::make_heap(refs.begin(),refs.end());
while (refs.size()+3 <= extSize)
while (refs.size()+N-1 <= extSize)
{
std::pop_heap (refs.begin(),refs.end());
NodeRef ref = refs.back().node;
+3 -3
View File
@@ -134,13 +134,13 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const {
if (!valid(i, getTimeSegmentRange(time_range, fnumTimeSegments))) return false;
if (!valid(i, timeSegmentRange(time_range))) return false;
bbox = linearBounds(i, time_range);
return true;
}
+52
View File
@@ -233,4 +233,56 @@ namespace embree
typedef BBox<Vec3vf4> BBox3vf4;
typedef BBox<Vec3vf8> BBox3vf8;
typedef BBox<Vec3vf16> BBox3vf16;
/* calculate time segment itime and fractional time ftime */
__forceinline int getTimeSegment(float time, float numTimeSegments, float& ftime)
{
const float timeScaled = time * numTimeSegments;
const float itimef = clamp(floorf(timeScaled), 0.0f, numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return int(itimef);
}
__forceinline int getTimeSegment(float time, float start_time, float end_time, float numTimeSegments, float& ftime)
{
const float timeScaled = (time-start_time)/(end_time-start_time) * numTimeSegments;
const float itimef = clamp(floorf(timeScaled), 0.0f, numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return int(itimef);
}
template<int N>
__forceinline vint<N> getTimeSegment(const vfloat<N>& time, const vfloat<N>& numTimeSegments, vfloat<N>& ftime)
{
const vfloat<N> timeScaled = time * numTimeSegments;
const vfloat<N> itimef = clamp(floor(timeScaled), vfloat<N>(zero), numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return vint<N>(itimef);
}
template<int N>
__forceinline vint<N> getTimeSegment(const vfloat<N>& time, const vfloat<N>& start_time, const vfloat<N>& end_time, const vfloat<N>& numTimeSegments, vfloat<N>& ftime)
{
const vfloat<N> timeScaled = (time-start_time)/(end_time-start_time) * numTimeSegments;
const vfloat<N> itimef = clamp(floor(timeScaled), vfloat<N>(zero), numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return vint<N>(itimef);
}
/* calculate overlapping time segment range */
__forceinline range<int> getTimeSegmentRange(const BBox1f& time_range, float numTimeSegments)
{
const int itime_lower = (int)max(floor(time_range.lower*numTimeSegments), 0.0f);
const int itime_upper = (int)min(ceil (time_range.upper*numTimeSegments), numTimeSegments);
return make_range(itime_lower, itime_upper);
}
/* calculate overlapping time segment range */
__forceinline range<int> getTimeSegmentRange(const BBox1f& range, BBox1f time_range, float numTimeSegments)
{
const float lower = (range.lower-time_range.lower)/time_range.size();
const float upper = (range.upper-time_range.lower)/time_range.size();
return getTimeSegmentRange(BBox1f(lower,upper),numTimeSegments);
}
}
+7 -1
View File
@@ -47,7 +47,7 @@ namespace embree
Geometry::Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps)
: device(device), scene(nullptr), userPtr(nullptr),
geomID(0), numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)),
geomID(0), numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), time_range(0.0f,1.0f),
mask(-1),
gtype(gtype),
quality(RTC_BUILD_QUALITY_MEDIUM),
@@ -88,6 +88,12 @@ namespace embree
Geometry::update();
}
void Geometry::setTimeRange (const BBox1f range)
{
time_range = range;
Geometry::update();
}
void Geometry::update()
{
+31 -32
View File
@@ -25,32 +25,6 @@ namespace embree
{
class Scene;
/* calculate time segment itime and fractional time ftime */
__forceinline int getTimeSegment(float time, float numTimeSegments, float& ftime)
{
const float timeScaled = time * numTimeSegments;
const float itimef = clamp(floorf(timeScaled), 0.0f, numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return int(itimef);
}
template<int N>
__forceinline vint<N> getTimeSegment(const vfloat<N>& time, const vfloat<N>& numTimeSegments, vfloat<N>& ftime)
{
const vfloat<N> timeScaled = time * numTimeSegments;
const vfloat<N> itimef = clamp(floor(timeScaled), vfloat<N>(zero), numTimeSegments-1.0f);
ftime = timeScaled - itimef;
return vint<N>(itimef);
}
/* calculate overlapping time segment range */
__forceinline range<int> getTimeSegmentRange(const BBox1f& time_range, float numTimeSegments)
{
const int itime_lower = (int)floor(time_range.lower*numTimeSegments);
const int itime_upper = (int)ceil (time_range.upper*numTimeSegments);
return make_range(itime_lower, itime_upper);
}
/*! Base class all geometries are derived from */
class Geometry : public RefCount
{
@@ -187,6 +161,9 @@ namespace embree
/*! sets number of time steps */
virtual void setNumTimeSteps (unsigned int numTimeSteps_in);
/*! sets motion blur time range */
void setTimeRange (const BBox1f range);
/*! sets number of vertex attributes */
virtual void setVertexAttributeCount (unsigned int N) {
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry");
@@ -203,6 +180,27 @@ namespace embree
this->quality = quality_in;
Geometry::update();
}
/* calculate time segment itime and fractional time ftime */
__forceinline int timeSegment(float time, float& ftime) const {
return getTimeSegment(time,time_range.lower,time_range.upper,fnumTimeSegments,ftime);
}
template<int N>
__forceinline vint<N> timeSegment(const vfloat<N>& time, vfloat<N>& ftime) const {
return getTimeSegment(time,vfloat<N>(time_range.lower),vfloat<N>(time_range.upper),vfloat<N>(fnumTimeSegments),ftime);
}
/* calculate overlapping time segment range */
__forceinline range<int> timeSegmentRange(const BBox1f& range) const {
return getTimeSegmentRange(range,time_range,fnumTimeSegments);
}
/* returns time that corresponds to time step */
__forceinline float timeStep(const int i) const {
assert(i>=0 && i<numTimeSteps);
return time_range.lower + time_range.size()*float(i)/fnumTimeSegments;
}
/*! for all geometries */
public:
@@ -426,22 +424,23 @@ namespace embree
Device* device; //!< device this geometry belongs to
Scene* scene; //!< pointer to scene this mesh belongs to
void* userPtr; //!< user pointer
void* userPtr; //!< user pointer
unsigned int geomID; //!< internal geometry ID
unsigned int numPrimitives; //!< number of primitives of this geometry
unsigned int numTimeSteps; //!< number of time steps
float fnumTimeSegments; //!< number of time segments (precalculation)
unsigned int numTimeSteps; //!< number of time steps
float fnumTimeSegments; //!< number of time segments (precalculation)
BBox1f time_range; //!< motion blur time range
unsigned int mask; //!< for masking out geometry
struct {
GType gtype : 6; //!< geometry type
GType gtype : 6; //!< geometry type
RTCBuildQuality quality : 3; //!< build quality for geometry
State state : 2;
bool numPrimitivesChanged : 1; //!< true if number of primitives changed
bool enabled : 1; //!< true if geometry is enabled
};
public:
RTCFilterFunctionN intersectionFilterN;
RTCFilterFunctionN occlusionFilterN;
};
+34 -17
View File
@@ -129,18 +129,16 @@ namespace embree
__forceinline PrimRefMB () {}
__forceinline PrimRefMB (const LBBox3fa& bounds, unsigned int activeTimeSegments, unsigned int totalTimeSegments, unsigned int geomID, unsigned int primID)
: bbox(bounds.interpolate(0.5f))
__forceinline PrimRefMB (const LBBox3fa& bounds, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, unsigned int geomID, unsigned int primID)
: bbox(bounds.interpolate(0.5f)), _activeTimeSegments(activeTimeSegments), _totalTimeSegments(totalTimeSegments), time_range(time_range)
{
assert(activeTimeSegments > 0);
bbox.lower.a = geomID;
bbox.upper.a = primID;
num.x = activeTimeSegments;
num.y = totalTimeSegments;
}
__forceinline PrimRefMB (const LBBox3fa& bounds, unsigned int activeTimeSegments, unsigned int totalTimeSegments, size_t id)
: bbox(bounds.interpolate(0.5f))
__forceinline PrimRefMB (EmptyTy empty, const LBBox3fa& bounds, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, size_t id)
: bbox(bounds.interpolate(0.5f)), _activeTimeSegments(activeTimeSegments), _totalTimeSegments(totalTimeSegments), time_range(time_range)
{
assert(activeTimeSegments > 0);
#if defined(__X86_64__)
@@ -150,22 +148,39 @@ namespace embree
bbox.lower.u = id;
bbox.upper.u = 0;
#endif
num.x = activeTimeSegments;
num.y = totalTimeSegments;
}
/*! returns bounds for binning */
__forceinline BBox3fa bounds() const {
return bbox;
}
/*! returns the number of time segments of this primref */
__forceinline unsigned size() const {
return num.x;
__forceinline unsigned int size() const {
return _activeTimeSegments;
}
__forceinline unsigned totalTimeSegments() const {
return num.y;
__forceinline unsigned int totalTimeSegments() const {
return _totalTimeSegments;
}
/* calculate overlapping time segment range */
__forceinline range<int> timeSegmentRange(const BBox1f& range) const {
return getTimeSegmentRange(range,time_range,float(_totalTimeSegments));
}
/* returns time that corresponds to time step */
__forceinline float timeStep(const int i) const {
assert(i>=0 && i<=_totalTimeSegments);
return time_range.lower + time_range.size()*float(i)/float(_totalTimeSegments);
}
/*! checks if time range overlaps */
__forceinline bool time_range_overlap(const BBox1f& range) const
{
if (0.9999f*time_range.upper <= range.lower) return false;
if (1.0001f*time_range.lower >= range.upper) return false;
return true;
}
/*! returns center for binning */
@@ -181,12 +196,12 @@ namespace embree
}
/*! returns the geometry ID */
__forceinline unsigned geomID() const {
__forceinline unsigned int geomID() const {
return bbox.lower.a;
}
/*! returns the primitive ID */
__forceinline unsigned primID() const {
__forceinline unsigned int primID() const {
return bbox.upper.a;
}
@@ -216,7 +231,9 @@ namespace embree
public:
BBox3fa bbox; // bounds, geomID, primID
Vec3ia num; // activeTimeSegments, totalTimeSegments
unsigned int _activeTimeSegments;
unsigned int _totalTimeSegments;
BBox1f time_range; // entire geometry time range
};
#endif
+14
View File
@@ -1086,6 +1086,20 @@ namespace embree
RTC_CATCH_END2(geometry);
}
RTC_API void rtcSetGeometryTimeRange(RTCGeometry hgeometry, float startTime, float endTime)
{
Ref<Geometry> geometry = (Geometry*) hgeometry;
RTC_CATCH_BEGIN;
RTC_TRACE(rtcSetGeometryTimeRange);
RTC_VERIFY_HANDLE(hgeometry);
if (startTime > endTime)
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"startTime has to be smaller or equal to the endTime");
geometry->setTimeRange(BBox1f(startTime,endTime));
RTC_CATCH_END2(geometry);
}
RTC_API void rtcSetGeometryVertexAttributeCount(RTCGeometry hgeometry, unsigned int N)
{
Geometry* geometry = (Geometry*) hgeometry;
+9 -10
View File
@@ -692,8 +692,7 @@ namespace embree
Vec3fa axisz(0,0,1);
Vec3fa axisy(0,1,0);
const unsigned num_time_segments = this->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
const range<int> tbounds = this->timeSegmentRange(time_range);
if (tbounds.size() == 0) return frame(axisz);
const size_t t = (tbounds.begin()+tbounds.end())/2;
@@ -769,18 +768,18 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, this->time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, dt, this->time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(ofs, scale, r_scale0, space, primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(ofs, scale, r_scale0, space, primID, itime); }, dt, this->time_range, fnumTimeSegments);
}
PrimInfo createPrimRefArray(mvector<PrimRef>& prims, const range<size_t>& r, size_t k) const
@@ -803,10 +802,10 @@ namespace embree
PrimInfoMB pinfo(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!valid(ctype, j, getTimeSegmentRange(t0t1, fnumTimeSegments))) continue;
if (!valid(ctype, j, this->timeSegmentRange(t0t1))) continue;
const LBBox3fa lbox = linearBounds(j,t0t1);
if (lbox.bounds0.empty() || lbox.bounds1.empty()) continue; // checks oriented curves with invalid normals which cause NaNs here
const PrimRefMB prim(lbox,this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(j));
const PrimRefMB prim(lbox,this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(j));
pinfo.add_primref(prim);
prims[k++] = prim;
}
+4 -4
View File
@@ -165,7 +165,7 @@ namespace embree
__forceinline void gather(Vec3fa& p0, Vec3fa& p1, Vec3fa& p2, Vec3fa& p3, size_t i, float time) const
{
float ftime;
const size_t itime = getTimeSegment(time, fnumTimeSegments, ftime);
const size_t itime = timeSegment(time, ftime);
const float t0 = 1.0f - ftime;
const float t1 = ftime;
@@ -183,7 +183,7 @@ namespace embree
__forceinline void gather(Vec3fa& p0, Vec3fa& p1, Vec3fa& p2, Vec3fa& p3, Vec3fa& n0, Vec3fa& n1, size_t i, float time) const
{
float ftime;
const size_t itime = getTimeSegment(time, fnumTimeSegments, ftime);
const size_t itime = timeSegment(time, ftime);
const float t0 = 1.0f - ftime;
const float t1 = ftime;
@@ -221,7 +221,7 @@ namespace embree
__forceinline void gather_hermite(Vec3fa& p0, Vec3fa& t0, Vec3fa& p1, Vec3fa& t1, size_t i, float time) const
{
float ftime;
const size_t itime = getTimeSegment(time, fnumTimeSegments, ftime);
const size_t itime = timeSegment(time, ftime);
const float f0 = 1.0f - ftime, f1 = ftime;
Vec3fa ap0,at0,ap1,at1;
gather_hermite(ap0,at0,ap1,at1,i,itime);
@@ -259,7 +259,7 @@ namespace embree
__forceinline void gather_hermite(Vec3fa& p0, Vec3fa& t0, Vec3fa& n0, Vec3fa& p1, Vec3fa& t1, Vec3fa& n1, size_t i, float time) const
{
float ftime;
const size_t itime = getTimeSegment(time, fnumTimeSegments, ftime);
const size_t itime = timeSegment(time, ftime);
const float f0 = 1.0f - ftime, f1 = ftime;
Vec3fa ap0,at0,an0,ap1,at1,an1;
gather_hermite(ap0,at0,an0,ap1,at1,an1,i,itime);
+2 -3
View File
@@ -201,9 +201,8 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(const Grid& g, size_t sx, size_t sy, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(g,sx,sy,itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(const Grid& g, size_t sx, size_t sy, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(g,sx,sy,itime); }, dt, time_range, fnumTimeSegments);
}
/* returns true if topology changed */
+7 -8
View File
@@ -66,9 +66,9 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t i, const BBox1f& time_range) const {
__forceinline LBBox3fa linearBounds(size_t i, const BBox1f& dt) const {
assert(i == 0);
return LBBox3fa([&] (size_t itime) { return bounds(i, itime); }, time_range, fnumTimeSegments);
return LBBox3fa([&] (size_t itime) { return bounds(i, itime); }, dt, time_range, fnumTimeSegments);
}
/*! check if the i'th primitive is valid between the specified time range */
@@ -85,10 +85,9 @@ namespace embree
return local2world[0];
}
__forceinline AffineSpace3fa getLocal2World(float t) const
__forceinline AffineSpace3fa getLocal2World(float t) const
{
float ftime;
const unsigned int itime = getTimeSegment(t, fnumTimeSegments, ftime);
float ftime; const unsigned int itime = timeSegment(t, ftime);
return lerp(local2world[itime+0],local2world[itime+1],ftime);
}
@@ -104,7 +103,7 @@ namespace embree
__forceinline AffineSpace3vf<K> getWorld2Local(const vbool<K>& valid, const vfloat<K>& t) const
{
vfloat<K> ftime;
const vint<K> itime_k = getTimeSegment(t, vfloat<K>(fnumTimeSegments), ftime);
const vint<K> itime_k = timeSegment(t, ftime);
assert(any(valid));
const size_t index = bsf(movemask(valid));
const int itime = itime_k[index];
@@ -171,8 +170,8 @@ namespace embree
assert(r.end() == 1);
PrimInfoMB pinfo(empty);
if (!valid(0, getTimeSegmentRange(t0t1, fnumTimeSegments))) return pinfo;
const PrimRefMB prim(linearBounds(0,t0t1),this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(0));
if (!valid(0, timeSegmentRange(t0t1))) return pinfo;
const PrimRefMB prim(linearBounds(0,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(0));
pinfo.add_primref(prim);
prims[k++] = prim;
return pinfo;
+7 -7
View File
@@ -197,19 +197,19 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, dt, time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const
{
if (!valid(i, getTimeSegmentRange(time_range, fnumTimeSegments))) return false;
if (!valid(i, timeSegmentRange(time_range))) return false;
bbox = linearBounds(i, time_range);
return true;
}
@@ -286,8 +286,8 @@ namespace embree
PrimInfoMB pinfo(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!valid(j, getTimeSegmentRange(t0t1, fnumTimeSegments))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(j));
if (!valid(j, timeSegmentRange(t0t1))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(j));
pinfo.add_primref(prim);
prims[k++] = prim;
}
+7 -7
View File
@@ -193,15 +193,15 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const
__forceinline bool linearBounds(size_t i, const BBox1f& dt, LBBox3fa& bbox) const
{
if (!valid(i, getTimeSegmentRange(time_range, fnumTimeSegments))) return false;
bbox = linearBounds(i, time_range);
if (!valid(i, timeSegmentRange(dt))) return false;
bbox = linearBounds(i, dt);
return true;
}
@@ -257,8 +257,8 @@ namespace embree
PrimInfoMB pinfo(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!valid(j, getTimeSegmentRange(t0t1, fnumTimeSegments))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(j));
if (!valid(j, timeSegmentRange(t0t1))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(j));
pinfo.add_primref(prim);
prims[k++] = prim;
}
+7 -7
View File
@@ -192,14 +192,14 @@ namespace embree
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& time_range) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, time_range, fnumTimeSegments);
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
}
/*! calculates the linear bounds of the i'th primitive for the specified time range */
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const {
if (!valid(i, getTimeSegmentRange(time_range, fnumTimeSegments))) return false;
bbox = linearBounds(i, time_range);
__forceinline bool linearBounds(size_t i, const BBox1f& dt, LBBox3fa& bbox) const {
if (!valid(i, timeSegmentRange(dt))) return false;
bbox = linearBounds(i, dt);
return true;
}
@@ -255,8 +255,8 @@ namespace embree
PrimInfoMB pinfo(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!valid(j, getTimeSegmentRange(t0t1, fnumTimeSegments))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(j));
if (!valid(j, timeSegmentRange(t0t1))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(j));
pinfo.add_primref(prim);
prims[k++] = prim;
}
+2 -2
View File
@@ -77,8 +77,8 @@ namespace embree
PrimInfoMB pinfo(empty);
for (size_t j=r.begin(); j<r.end(); j++)
{
if (!valid(j, getTimeSegmentRange(t0t1, fnumTimeSegments))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->numTimeSegments(),this->geomID,unsigned(j));
if (!valid(j, timeSegmentRange(t0t1))) continue;
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),this->geomID,unsigned(j));
pinfo.add_primref(prim);
prims[k++] = prim;
}
+4 -4
View File
@@ -138,10 +138,10 @@ namespace embree
template<typename BVH, typename SetMB, typename Allocator>
__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)
{
size_t start = prims.object_range.begin();
size_t end = prims.object_range.end();
size_t items = CurveNiMB::blocks(prims.object_range.size());
size_t numbytes = CurveNiMB::bytes(prims.object_range.size());
size_t start = prims.begin();
size_t end = prims.end();
size_t items = CurveNiMB::blocks(prims.size());
size_t numbytes = CurveNiMB::bytes(prims.size());
CurveNiMB* accel = (CurveNiMB*) alloc.malloc1(numbytes,BVH::byteAlignment);
const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel,items);
+41 -41
View File
@@ -94,7 +94,7 @@ namespace embree
__forceinline void gather(Vec4vf<M>& p0,
Vec4vf<M>& p1,
const LineSegments* geom,
const vint<M>& itime) const;
const int itime) const;
__forceinline void gather(Vec4vf<M>& p0,
Vec4vf<M>& p1,
@@ -203,10 +203,10 @@ namespace embree
template<typename BVH, typename SetMB, typename Allocator>
__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)
{
size_t start = prims.object_range.begin();
size_t end = prims.object_range.end();
size_t items = LineMi::blocks(prims.object_range.size());
size_t numbytes = LineMi::bytes(prims.object_range.size());
size_t start = prims.begin();
size_t end = prims.end();
size_t items = LineMi::blocks(prims.size());
size_t numbytes = LineMi::bytes(prims.size());
LineMi* accel = (LineMi*) alloc.malloc1(numbytes,M*sizeof(float));
const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel,items);
@@ -269,18 +269,18 @@ namespace embree
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
Vec4vf4& p1,
const LineSegments* geom,
const vint4& itime) const
const int itime) const
{
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime[0]));
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime[1]));
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime[2]));
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime[3]));
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime[0]));
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime[1]));
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime[2]));
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime[3]));
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
}
@@ -291,16 +291,16 @@ namespace embree
float time) const
{
const LineSegments* geom = scene->get<LineSegments>(geomID());
const vfloat4 numTimeSegments(geom->fnumTimeSegments);
vfloat4 ftime;
const vint4 itime = getTimeSegment(vfloat4(time), numTimeSegments, ftime);
float ftime;
const int itime = geom->timeSegment(time, ftime);
Vec4vf4 a0,a1;
gather(a0,a1,geom,itime);
Vec4vf4 b0,b1;
gather(b0,b1,geom,itime+1);
p0 = lerp(a0,b0,ftime);
p1 = lerp(a1,b1,ftime);
p0 = lerp(a0,b0,vfloat4(ftime));
p1 = lerp(a1,b1,vfloat4(ftime));
}
#if defined(__AVX__)
@@ -337,26 +337,26 @@ namespace embree
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
Vec4vf8& p1,
const LineSegments* geom,
const vint8& itime) const
const int itime) const
{
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime[0]));
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime[1]));
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime[2]));
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime[3]));
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime[4]));
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime[5]));
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime[6]));
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime[7]));
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime));
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime));
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime));
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime));
transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime[0]));
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime[1]));
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime[2]));
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime[3]));
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime[4]));
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime[5]));
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime[6]));
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime[7]));
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime));
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime));
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime));
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime));
transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);
}
@@ -367,16 +367,16 @@ namespace embree
float time) const
{
const LineSegments* geom = scene->get<LineSegments>(geomID());
const vfloat8 numTimeSegments(geom->fnumTimeSegments);
vfloat8 ftime;
const vint8 itime = getTimeSegment(vfloat8(time), numTimeSegments, ftime);
float ftime;
const int itime = geom->timeSegment(time, ftime);
Vec4vf8 a0,a1;
gather(a0,a1,geom,itime);
Vec4vf8 b0,b1;
gather(b0,b1,geom,itime+1);
p0 = lerp(a0,b0,ftime);
p1 = lerp(a1,b1,ftime);
p0 = lerp(a0,b0,vfloat8(ftime));
p1 = lerp(a1,b1,vfloat8(ftime));
}
#endif
+18 -28
View File
@@ -144,7 +144,7 @@ namespace embree
const QuadMesh* mesh = scene->get<QuadMesh>(geomID(index));
vfloat<K> ftime;
const vint<K> itime = getTimeSegment(time, vfloat<K>(mesh->fnumTimeSegments), ftime);
const vint<K> itime = mesh->timeSegment(time, ftime);
const size_t first = bsf(movemask(valid));
if (likely(all(valid,itime[first] == itime)))
@@ -167,11 +167,8 @@ namespace embree
Vec3vf<M>& p1,
Vec3vf<M>& p2,
Vec3vf<M>& p3,
const QuadMesh* mesh0,
const QuadMesh* mesh1,
const QuadMesh* mesh2,
const QuadMesh* mesh3,
const vint<M>& itime) const;
const QuadMesh* mesh,
const int itime) const;
__forceinline void gather(Vec3vf<M>& p0,
Vec3vf<M>& p1,
@@ -402,16 +399,13 @@ namespace embree
Vec3vf4& p1,
Vec3vf4& p2,
Vec3vf4& p3,
const QuadMesh* mesh0,
const QuadMesh* mesh1,
const QuadMesh* mesh2,
const QuadMesh* mesh3,
const vint4& itime) const
const QuadMesh* mesh,
const int itime) const
{
const float* vertices0 = (const float*) mesh0->vertexPtr(0,itime[0]);
const float* vertices1 = (const float*) mesh1->vertexPtr(0,itime[1]);
const float* vertices2 = (const float*) mesh2->vertexPtr(0,itime[2]);
const float* vertices3 = (const float*) mesh3->vertexPtr(0,itime[3]);
const float* vertices0 = (const float*) mesh->vertexPtr(0,itime);
const float* vertices1 = (const float*) mesh->vertexPtr(0,itime);
const float* vertices2 = (const float*) mesh->vertexPtr(0,itime);
const float* vertices3 = (const float*) mesh->vertexPtr(0,itime);
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
@@ -442,21 +436,17 @@ namespace embree
const Scene *const scene,
const float time) const
{
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomID(0));
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomID(1));
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomID(2));
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomID(3));
const QuadMesh* mesh = scene->get<QuadMesh>(geomID(0)); // in mblur mode all geometries are identical
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
vfloat4 ftime;
const vint4 itime = getTimeSegment(vfloat4(time), numTimeSegments, ftime);
float ftime;
const int itime = mesh->timeSegment(time, ftime);
Vec3vf4 a0,a1,a2,a3; gather(a0,a1,a2,a3,mesh0,mesh1,mesh2,mesh3,itime);
Vec3vf4 b0,b1,b2,b3; gather(b0,b1,b2,b3,mesh0,mesh1,mesh2,mesh3,itime+1);
p0 = lerp(a0,b0,ftime);
p1 = lerp(a1,b1,ftime);
p2 = lerp(a2,b2,ftime);
p3 = lerp(a3,b3,ftime);
Vec3vf4 a0,a1,a2,a3; gather(a0,a1,a2,a3,mesh,itime);
Vec3vf4 b0,b1,b2,b3; gather(b0,b1,b2,b3,mesh,itime+1);
p0 = lerp(a0,b0,vfloat4(ftime));
p1 = lerp(a1,b1,vfloat4(ftime));
p2 = lerp(a2,b2,vfloat4(ftime));
p3 = lerp(a3,b3,vfloat4(ftime));
}
template<int M>
+4 -4
View File
@@ -35,7 +35,7 @@ namespace embree
const GridMesh::Grid &g = mesh->grid(subgrid.primID());
float ftime;
const int itime = getTimeSegment(ray.time(), float(mesh->fnumTimeSegments), ftime);
const int itime = mesh->timeSegment(ray.time(), ftime);
Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime,ftime);
pre.intersect(ray,context,v0,v1,v2,v3,g,subgrid);
}
@@ -47,7 +47,7 @@ namespace embree
const GridMesh::Grid &g = mesh->grid(subgrid.primID());
float ftime;
const int itime = getTimeSegment(ray.time(), float(mesh->fnumTimeSegments), ftime);
const int itime = mesh->timeSegment(ray.time(), ftime);
Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime,ftime);
return pre.occluded(ray,context,v0,v1,v2,v3,g,subgrid);
@@ -134,7 +134,7 @@ namespace embree
const GridMesh::Grid &g = mesh->grid(subgrid.primID());
vfloat<K> ftime;
const vint<K> itime = getTimeSegment(ray.time(), vfloat<K>(mesh->fnumTimeSegments), ftime);
const vint<K> itime = mesh->timeSegment(ray.time(), ftime);
Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]);
pre.intersect1(ray,k,context,v0,v1,v2,v3,g,subgrid);
}
@@ -146,7 +146,7 @@ namespace embree
const GridMesh::Grid &g = mesh->grid(subgrid.primID());
vfloat<K> ftime;
const vint<K> itime = getTimeSegment(ray.time(), vfloat<K>(mesh->fnumTimeSegments), ftime);
const vint<K> itime = mesh->timeSegment(ray.time(), ftime);
Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]);
return pre.occluded1(ray,k,context,v0,v1,v2,v3,g,subgrid);
}
+26 -39
View File
@@ -129,7 +129,7 @@ namespace embree
const TriangleMesh* mesh = scene->get<TriangleMesh>(geomID(index));
vfloat<K> ftime;
const vint<K> itime = getTimeSegment(time, vfloat<K>(mesh->fnumTimeSegments), ftime);
const vint<K> itime = mesh->timeSegment(time, ftime);
const size_t first = bsf(movemask(valid));
if (likely(all(valid,itime[first] == itime)))
@@ -147,11 +147,8 @@ namespace embree
__forceinline void gather(Vec3vf<M>& p0,
Vec3vf<M>& p1,
Vec3vf<M>& p2,
const TriangleMesh* mesh0,
const TriangleMesh* mesh1,
const TriangleMesh* mesh2,
const TriangleMesh* mesh3,
const vint<M>& itime) const;
const TriangleMesh* mesh,
const int itime) const;
__forceinline void gather(Vec3vf<M>& p0,
Vec3vf<M>& p1,
@@ -315,28 +312,22 @@ namespace embree
__forceinline void TriangleMi<4>::gather(Vec3vf4& p0,
Vec3vf4& p1,
Vec3vf4& p2,
const TriangleMesh* mesh0,
const TriangleMesh* mesh1,
const TriangleMesh* mesh2,
const TriangleMesh* mesh3,
const vint4& itime) const
const TriangleMesh* mesh,
const int itime) const
{
const float* vertices0 = (const float*) mesh0->vertexPtr(0,itime[0]);
const float* vertices1 = (const float*) mesh1->vertexPtr(0,itime[1]);
const float* vertices2 = (const float*) mesh2->vertexPtr(0,itime[2]);
const float* vertices3 = (const float*) mesh3->vertexPtr(0,itime[3]);
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
const vfloat4 a3 = vfloat4::loadu(vertices3 + v0[3]);
const vfloat4 b0 = vfloat4::loadu(vertices0 + v1[0]);
const vfloat4 b1 = vfloat4::loadu(vertices1 + v1[1]);
const vfloat4 b2 = vfloat4::loadu(vertices2 + v1[2]);
const vfloat4 b3 = vfloat4::loadu(vertices3 + v1[3]);
const vfloat4 c0 = vfloat4::loadu(vertices0 + v2[0]);
const vfloat4 c1 = vfloat4::loadu(vertices1 + v2[1]);
const vfloat4 c2 = vfloat4::loadu(vertices2 + v2[2]);
const vfloat4 c3 = vfloat4::loadu(vertices3 + v2[3]);
const float* vertices = (const float*) mesh->vertexPtr(0,itime);
const vfloat4 a0 = vfloat4::loadu(vertices + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices + v0[1]);
const vfloat4 a2 = vfloat4::loadu(vertices + v0[2]);
const vfloat4 a3 = vfloat4::loadu(vertices + v0[3]);
const vfloat4 b0 = vfloat4::loadu(vertices + v1[0]);
const vfloat4 b1 = vfloat4::loadu(vertices + v1[1]);
const vfloat4 b2 = vfloat4::loadu(vertices + v1[2]);
const vfloat4 b3 = vfloat4::loadu(vertices + v1[3]);
const vfloat4 c0 = vfloat4::loadu(vertices + v2[0]);
const vfloat4 c1 = vfloat4::loadu(vertices + v2[1]);
const vfloat4 c2 = vfloat4::loadu(vertices + v2[2]);
const vfloat4 c3 = vfloat4::loadu(vertices + v2[3]);
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z);
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z);
transpose(c0,c1,c2,c3,p2.x,p2.y,p2.z);
@@ -349,20 +340,16 @@ namespace embree
const Scene *const scene,
const float time) const
{
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomID(0));
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomID(1));
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomID(2));
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomID(3));
const TriangleMesh* mesh = scene->get<TriangleMesh>(geomID(0)); // in mblur mode all geometries are identical
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
vfloat4 ftime;
const vint4 itime = getTimeSegment(vfloat4(time), numTimeSegments, ftime);
float ftime;
const int itime = mesh->timeSegment(time, ftime);
Vec3vf4 a0,a1,a2; gather(a0,a1,a2,mesh0,mesh1,mesh2,mesh3,itime);
Vec3vf4 b0,b1,b2; gather(b0,b1,b2,mesh0,mesh1,mesh2,mesh3,itime+1);
p0 = lerp(a0,b0,ftime);
p1 = lerp(a1,b1,ftime);
p2 = lerp(a2,b2,ftime);
Vec3vf4 a0,a1,a2; gather(a0,a1,a2,mesh,itime);
Vec3vf4 b0,b1,b2; gather(b0,b1,b2,mesh,itime+1);
p0 = lerp(a0,b0,vfloat4(ftime));
p1 = lerp(a1,b1,vfloat4(ftime));
p2 = lerp(a2,b2,vfloat4(ftime));
}
template<int M>
+2 -3
View File
@@ -167,8 +167,7 @@ namespace embree
const unsigned geomID = prim.geomID();
const unsigned primID = prim.primID();
const TriangleMesh* const mesh = scene->get<TriangleMesh>(geomID);
const unsigned numTimeSegments = mesh->numTimeSegments();
const range<int> itime_range = getTimeSegmentRange(time_range, (float)numTimeSegments);
const range<int> itime_range = mesh->timeSegmentRange(time_range);
assert(itime_range.size() == 1);
const int ilower = itime_range.begin();
const TriangleMesh::Triangle& tri = mesh->triangle(primID);
@@ -179,7 +178,7 @@ namespace embree
const Vec3fa& b1 = mesh->vertex(tri.v[1],ilower+1);
const Vec3fa& c0 = mesh->vertex(tri.v[2],ilower+0);
const Vec3fa& c1 = mesh->vertex(tri.v[2],ilower+1);
const BBox1f time_range_v(float(ilower+0)/float(numTimeSegments),float(ilower+1)/float(numTimeSegments));
const BBox1f time_range_v(mesh->timeStep(ilower+0),mesh->timeStep(ilower+1));
auto a01 = globalLinear(std::make_pair(a0,a1),time_range_v);
auto b01 = globalLinear(std::make_pair(b0,b1),time_range_v);
auto c01 = globalLinear(std::make_pair(c0,c1),time_range_v);
+58
View File
@@ -0,0 +1,58 @@
.TH "rtcSetGeometryTimeRange" "3" "" "" "Embree Ray Tracing Kernels 3"
.SS NAME
.IP
.nf
\f[C]
rtcSetGeometryTimeRange\ \-\ sets\ the\ time\ range\ for\ a\ motion\ blur\ geometry
\f[]
.fi
.SS SYNOPSIS
.IP
.nf
\f[C]
#include\ <embree3/rtcore.h>
void\ rtcSetGeometryTimeRange(
\ \ RTCGeometry\ geometry,
\ \ float\ startTime,
\ \ float\ endTime
);
\f[]
.fi
.SS DESCRIPTION
.PP
The \f[C]rtcSetGeometryTimeRange\f[] function sets a time range which
defines the start (and end time) of the first (and last) time step of a
motion blur geometry.
The time range is defined relative to the camera shutter interval [0,1]
but it can be arbitrary.
Thus the startTime can be smaller, equal, or larger 0, indicating a
geometry whose animation definition start before, at, or after the
camera shutter opens.
Similar the endTime can be smaller, equal, or larger than 1, indicating
a geometry whose animation definition ends after, at, or before the
camera shutter closes.
The startTime has to be smaller or equal to the endTime.
.PP
The default time range when this function is not called is the entire
camera shutter [0,1].
For best performance at most one time segment of the piece wise linear
definition of the motion should fall outside the shutter window to the
left and to the right.
Thus do not set the startTime or endTime too far outside the [0,1]
interval for best performance.
.PP
This time range feature will also allow geometries to appear and
disappear during the camera shutter time if the specified time range is
a sub range of [0,1].
.PP
Please also have a look at the \f[C]rtcSetGeometryTimeStepCount\f[]
function to see how to define the time steps for the specified time
range.
.SS EXIT STATUS
.PP
On failure an error code is set that can be queried using
\f[C]rtcDeviceGetError\f[].
.SS SEE ALSO
.PP
[rtcSetGeometryTimeStepCount]
@@ -48,4 +48,4 @@ On failure an error code is set that can be queried using
\f[C]rtcDeviceGetError\f[].
.SS SEE ALSO
.PP
[rtcNewGeometry]
[rtcNewGeometry], [rtcSetGeometryTimeRange]
BIN
View File
Binary file not shown.
+4 -4
View File
@@ -105,10 +105,10 @@ def runConfig(config):
elif (compiler == "ICC18"):
conf.append("-G \"Visual Studio 12 2013"+ext+"\"")
conf.append("-T \"Intel C++ Compiler 18.0\"")
elif (compiler == "ICC17-VS14"):
elif (compiler == "ICC17-VC14"):
conf.append("-G \"Visual Studio 14 2015"+ext+"\"")
conf.append("-T \"Intel C++ Compiler 17.0\"")
elif (compiler == "ICC17-VS12"):
elif (compiler == "ICC17-VC12"):
conf.append("-G \"Visual Studio 12 2013"+ext+"\"")
conf.append("-T \"Intel C++ Compiler 17.0\"")
elif (compiler == "ICC17"):
@@ -235,9 +235,9 @@ def runConfig(config):
raise ValueError('unknown tasking system: ' + tasking + '')
if platform == "x64":
env.append("set PATH="+tbb_path+"\\bin\\intel64\\vc12;%PATH%")
env.append("set PATH="+tbb_path+"\\bin\\intel64\\vc12;"+tbb_path+"\\bin\\intel64\\vc14;%PATH%")
else:
env.append("set PATH="+tbb_path+"\\bin\\ia32\\vc12;%PATH%")
env.append("set PATH="+tbb_path+"\\bin\\ia32\\vc12;"+tbb_path+"\\bin\\ia32\\vc14;%PATH%")
else:
sys.stderr.write("unknown operating system "+OS)
+26
View File
@@ -23,9 +23,26 @@
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
#include "../math/vec.h"
#include "../math/linearspace.h"
namespace embree {
struct Sample3f
{
Vec3fa v;
float pdf;
};
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
inline Vec3fa cartesian(const float phi, const float sinTheta, const float cosTheta)
{
@@ -63,6 +80,15 @@ inline float cosineSampleHemispherePDF(float cosTheta)
return cosTheta / float(pi);
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3fa& N)
{
Vec3fa localDir = cosineSampleHemisphere(Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
+25
View File
@@ -23,7 +23,23 @@
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
#include "../math/vec.isph"
#include "../math/linearspace.isph"
struct Sample3f
{
Vec3f v;
float pdf;
};
inline uniform Sample3f make_Sample3f(const uniform Vec3f& v, const uniform float pdf) {
uniform Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3f& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
inline Vec3f cartesian(const float phi, const float sinTheta, const float cosTheta)
{
@@ -61,6 +77,15 @@ inline float cosineSampleHemispherePDF(float cosTheta)
return cosTheta / M_PI;
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3f& N)
{
Vec3f localDir = cosineSampleHemisphere(make_Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
@@ -20,7 +20,7 @@ namespace embree
{
Ref<SceneGraph::Node> SceneGraph::createTrianglePlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
{
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,1);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize((width+1)*(height+1));
mesh->triangles.resize(2*width*height);
@@ -49,7 +49,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::createQuadPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
{
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,1);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize((width+1)*(height+1));
mesh->quads.resize(width*height);
@@ -80,7 +80,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::createGridPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
{
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,1);
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize((width+1)*(height+1));
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(0,width+1,width+1,height+1));
@@ -98,7 +98,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::createSubdivPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, float tessellationRate, Ref<MaterialNode> material)
{
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,1);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
mesh->tessellationRate = tessellationRate;
mesh->positions[0].resize((width+1)*(height+1));
mesh->position_indices.resize(4*width*height);
@@ -136,7 +136,7 @@ namespace embree
unsigned numPhi = unsigned(N);
unsigned numTheta = 2*numPhi;
unsigned numVertices = numTheta*(numPhi+1);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,1);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize(numVertices);
/* create sphere geometry */
@@ -195,7 +195,7 @@ namespace embree
unsigned numPhi = unsigned(N);
unsigned numTheta = 2*numPhi;
unsigned numVertices = numTheta*(numPhi+1);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,1);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize(numVertices);
/* create sphere geometry */
@@ -251,7 +251,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::createGridSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
{
size_t grid_size = (N+1)*(N+1);
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,1);
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
mesh->positions[0].resize(grid_size*6);
for (size_t i=0; i<6; i++)
@@ -284,7 +284,7 @@ namespace embree
unsigned numPhi = unsigned(N);
unsigned numTheta = 2*numPhi;
unsigned numVertices = numTheta*(numPhi+1);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,1);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
mesh->tessellationRate = tessellationRate;
mesh->positions[0].resize(numVertices);
@@ -350,7 +350,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::createSphereShapedHair(const Vec3fa& center, const float radius, Ref<MaterialNode> material)
{
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,1);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),1);
mesh->hairs.push_back(SceneGraph::HairSetNode::Hair(0,0));
mesh->positions[0].push_back(Vec3fa(center+Vec3fa(-radius,0,0),radius));
mesh->positions[0].push_back(Vec3fa(center+Vec3fa(0,0,0),radius));
@@ -365,7 +365,7 @@ namespace embree
RandomSampler_init(sampler,hash);
RTCGeometryType type = (subtype == ROUND_CURVE) ? RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE : RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,1);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,BBox1f(0,1),1);
if (numHairs == 1) {
const Vec3fa p0 = pos;
@@ -400,7 +400,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,mblur?2:1);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),mblur?2:1);
mesh->triangles.resize(numTriangles);
for (size_t i=0; i<numTriangles; i++) {
@@ -438,7 +438,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,mblur?2:1);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),mblur?2:1);
mesh->quads.resize(numQuads);
for (size_t i=0; i<numQuads; i++) {
@@ -477,7 +477,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,mblur?2:1);
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),mblur?2:1);
mesh->grids.resize(numGrids);
for (size_t i=0; i<numGrids; i++) {
@@ -513,7 +513,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,material,mblur?2:1);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,material,BBox1f(0,1),mblur?2:1);
mesh->hairs.resize(numLineSegments);
for (size_t i=0; i<numLineSegments; i++) {
@@ -549,7 +549,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,mblur?2:1);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),mblur?2:1);
mesh->hairs.resize(numHairs);
for (size_t i=0; i<numHairs; i++) {
@@ -585,7 +585,7 @@ namespace embree
{
RandomSampler sampler;
RandomSampler_init(sampler,hash);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,mblur?2:1);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),mblur?2:1);
for (size_t i=0; i<numFaces; i++)
{
+4 -2
View File
@@ -538,7 +538,8 @@ namespace embree
if (subdivMode)
{
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(curMaterial,1);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(curMaterial,BBox1f(0,1),1);
mesh->normals.resize(1);
group->add(mesh.cast<SceneGraph::Node>());
for (size_t i=0; i<v.size(); i++) mesh->positions[0].push_back(v[i]);
@@ -564,7 +565,8 @@ namespace embree
}
else
{
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(curMaterial,1);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(curMaterial,BBox1f(0,1),1);
mesh->normals.resize(1);
group->add(mesh.cast<SceneGraph::Node>());
// merge three indices into one
std::map<Vertex, uint32_t> vertexMap;
+1 -1
View File
@@ -302,7 +302,7 @@ namespace embree
Ref<SceneGraph::Node> import()
{
Ref<SceneGraph::MaterialNode> material = new OBJMaterial;
Ref<SceneGraph::TriangleMeshNode> mesh_o = new SceneGraph::TriangleMeshNode(material,1);
Ref<SceneGraph::TriangleMeshNode> mesh_o = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
/* convert all vertices */
const Element& vertices = mesh.elements.at("vertex");
+33 -6
View File
@@ -933,6 +933,33 @@ namespace embree
}
}
void SceneGraph::set_time_range(Ref<SceneGraph::Node> node, const BBox1f& time_range)
{
if (Ref<SceneGraph::TransformNode> xfmNode = node.dynamicCast<SceneGraph::TransformNode>()) {
xfmNode->spaces.time_range = time_range;
}
else if (Ref<SceneGraph::GroupNode> groupNode = node.dynamicCast<SceneGraph::GroupNode>())
{
for (size_t i=0; i<groupNode->children.size(); i++)
set_time_range(groupNode->children[i],time_range);
}
else if (Ref<SceneGraph::TriangleMeshNode> mesh = node.dynamicCast<SceneGraph::TriangleMeshNode>()) {
mesh->time_range = time_range;
}
else if (Ref<SceneGraph::QuadMeshNode> mesh = node.dynamicCast<SceneGraph::QuadMeshNode>()) {
mesh->time_range = time_range;
}
else if (Ref<SceneGraph::GridMeshNode> mesh = node.dynamicCast<SceneGraph::GridMeshNode>()) {
mesh->time_range = time_range;
}
else if (Ref<SceneGraph::HairSetNode> mesh = node.dynamicCast<SceneGraph::HairSetNode>()) {
mesh->time_range = time_range;
}
else if (Ref<SceneGraph::SubdivMeshNode> mesh = node.dynamicCast<SceneGraph::SubdivMeshNode>()) {
mesh->time_range = time_range;
}
}
std::pair<int,int> quad_index2(int p, int a0, int a1, int b0, int b1)
{
if (b0 == a0) return std::make_pair(p-1,b1);
@@ -958,7 +985,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::convert_triangles_to_quads ( Ref<SceneGraph::TriangleMeshNode> tmesh )
{
Ref<SceneGraph::QuadMeshNode> qmesh = new SceneGraph::QuadMeshNode(tmesh->material);
Ref<SceneGraph::QuadMeshNode> qmesh = new SceneGraph::QuadMeshNode(tmesh->material,tmesh->time_range,0);
for (auto& p : tmesh->positions)
qmesh->positions.push_back(p);
@@ -1015,7 +1042,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::convert_quads_to_grids ( Ref<SceneGraph::QuadMeshNode> qmesh , const unsigned int resX, const unsigned int resY )
{
const size_t timeSteps = qmesh->positions.size();
Ref<SceneGraph::GridMeshNode> gmesh = new SceneGraph::GridMeshNode(qmesh->material,timeSteps);
Ref<SceneGraph::GridMeshNode> gmesh = new SceneGraph::GridMeshNode(qmesh->material,qmesh->time_range,timeSteps);
std::vector<SceneGraph::QuadMeshNode::Quad>& quads = qmesh->quads;
for (size_t i=0;i<quads.size();i++)
@@ -1063,7 +1090,7 @@ namespace embree
Ref<SceneGraph::Node> SceneGraph::convert_grids_to_quads ( Ref<SceneGraph::GridMeshNode> gmesh )
{
Ref<SceneGraph::QuadMeshNode> qmesh = new SceneGraph::QuadMeshNode(gmesh->material);
Ref<SceneGraph::QuadMeshNode> qmesh = new SceneGraph::QuadMeshNode(gmesh->material,gmesh->time_range,0);
for (size_t i=0; i<gmesh->numPrimitives(); i++)
{
@@ -1226,7 +1253,7 @@ namespace embree
}
else if (Ref<SceneGraph::QuadMeshNode> qmesh = node.dynamicCast<SceneGraph::QuadMeshNode>())
{
Ref<SceneGraph::GridMeshNode> gmesh = new SceneGraph::GridMeshNode(qmesh->material,qmesh->numTimeSteps());
Ref<SceneGraph::GridMeshNode> gmesh = new SceneGraph::GridMeshNode(qmesh->material,qmesh->time_range,qmesh->numTimeSteps());
std::vector<bool> visited;
visited.resize(qmesh->numPrimitives());
@@ -1307,7 +1334,7 @@ namespace embree
}
else if (Ref<SceneGraph::QuadMeshNode> tmesh = node.dynamicCast<SceneGraph::QuadMeshNode>())
{
Ref<SceneGraph::SubdivMeshNode> smesh = new SceneGraph::SubdivMeshNode(tmesh->material);
Ref<SceneGraph::SubdivMeshNode> smesh = new SceneGraph::SubdivMeshNode(tmesh->material,tmesh->time_range,0);
for (auto& p : tmesh->positions)
smesh->positions.push_back(p);
@@ -1348,7 +1375,7 @@ namespace embree
}
else if (Ref<SceneGraph::HairSetNode> hmesh = node.dynamicCast<SceneGraph::HairSetNode>())
{
Ref<SceneGraph::HairSetNode> lmesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, hmesh->material);
Ref<SceneGraph::HairSetNode> lmesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, hmesh->material, hmesh->time_range, 0);
for (auto& p : hmesh->positions)
lmesh->positions.push_back(p);
+47 -29
View File
@@ -39,6 +39,7 @@ namespace embree
void optimize_animation(Ref<Node> node0);
void set_motion_vector(Ref<Node> node, const Vec3fa& dP);
void set_motion_vector(Ref<Node> node, const avector<Vec3fa>& motion_vector);
void set_time_range(Ref<SceneGraph::Node> node, const BBox1f& time_range);
void resize_randomly(RandomSampler& sampler, Ref<Node> node, const size_t N);
Ref<Node> convert_triangles_to_quads(Ref<Node> node, float prop);
Ref<Node> convert_triangles_to_quads( Ref<TriangleMeshNode> tmesh);
@@ -165,24 +166,30 @@ namespace embree
{
__forceinline Transformations() {}
__forceinline Transformations(OneTy) {
__forceinline Transformations(OneTy)
: time_range(0.0f,1.0f)
{
spaces.push_back(one);
}
__forceinline Transformations( size_t N )
: spaces(N) {}
__forceinline Transformations( const BBox1f& time_range, size_t N )
: time_range(time_range), spaces(N) {}
__forceinline Transformations(const AffineSpace3fa& space) {
__forceinline Transformations(const AffineSpace3fa& space)
: time_range(0.0f,1.0f)
{
spaces.push_back(space);
}
__forceinline Transformations(const AffineSpace3fa& space0, const AffineSpace3fa& space1) {
__forceinline Transformations(const AffineSpace3fa& space0, const AffineSpace3fa& space1)
: time_range(0.0f,1.0f)
{
spaces.push_back(space0);
spaces.push_back(space1);
}
__forceinline Transformations(const avector<AffineSpace3fa>& spaces)
: spaces(spaces) { assert(spaces.size()); }
: time_range(0.0f,1.0f), spaces(spaces) { assert(spaces.size()); }
__forceinline size_t size() const {
return spaces.size();
@@ -226,19 +233,19 @@ namespace embree
{
if (a.size() == 1)
{
Transformations c(b.size());
Transformations c(intersect(a.time_range,b.time_range),b.size());
for (size_t i=0; i<b.size(); i++) c[i] = a[0] * b[i];
return c;
}
else if (b.size() == 1)
{
Transformations c(a.size());
Transformations c(intersect(a.time_range,b.time_range),a.size());
for (size_t i=0; i<a.size(); i++) c[i] = a[i] * b[0];
return c;
}
else if (a.size() == b.size())
{
Transformations c(a.size());
Transformations c(intersect(a.time_range,b.time_range),a.size());
for (size_t i=0; i<a.size(); i++) c[i] = a[i] * b[i];
return c;
}
@@ -248,6 +255,7 @@ namespace embree
AffineSpace3fa interpolate (const float gtime) const
{
assert(time_range.lower == 0.0f && time_range.upper == 1.0f);
if (spaces.size() == 1) return spaces[0];
/* calculate time segment itime and fractional time ftime */
@@ -259,6 +267,7 @@ namespace embree
}
public:
BBox1f time_range;
avector<AffineSpace3fa> spaces;
};
@@ -617,23 +626,22 @@ namespace embree
const std::vector<Vec2f>& texcoords,
const std::vector<Triangle>& triangles,
Ref<MaterialNode> material)
: Node(true), texcoords(texcoords), triangles(triangles), material(material)
: Node(true), time_range(0.0f,1.0f), texcoords(texcoords), triangles(triangles), material(material)
{
positions.push_back(positions_in);
normals.push_back(normals_in);
}
TriangleMeshNode (Ref<MaterialNode> material, size_t numTimeSteps = 0)
: Node(true), material(material)
TriangleMeshNode (Ref<MaterialNode> material, const BBox1f time_range = BBox1f(0,1), size_t numTimeSteps = 0)
: Node(true), time_range(time_range), material(material)
{
for (size_t i=0; i<numTimeSteps; i++)
positions.push_back(avector<Vertex>());
for (size_t i=0; i<numTimeSteps; i++)
normals.push_back(avector<Vertex>());
}
TriangleMeshNode (Ref<SceneGraph::TriangleMeshNode> imesh, const Transformations& spaces)
: Node(true),
time_range(imesh->time_range),
positions(transformMSMBlurBuffer(imesh->positions,spaces)),
normals(transformMSMBlurNormalBuffer(imesh->normals,spaces)),
texcoords(imesh->texcoords), triangles(imesh->triangles), material(imesh->material) {}
@@ -686,6 +694,7 @@ namespace embree
virtual void resetInDegree();
public:
BBox1f time_range;
std::vector<avector<Vertex>> positions;
std::vector<avector<Vertex>> normals;
std::vector<Vec2f> texcoords;
@@ -709,17 +718,16 @@ namespace embree
};
public:
QuadMeshNode (Ref<MaterialNode> material, size_t numTimeSteps = 0)
: Node(true), material(material)
QuadMeshNode (Ref<MaterialNode> material, const BBox1f time_range = BBox1f(0,1), size_t numTimeSteps = 0 )
: Node(true), time_range(time_range), material(material)
{
for (size_t i=0; i<numTimeSteps; i++)
positions.push_back(avector<Vertex>());
for (size_t i=0; i<numTimeSteps; i++)
normals.push_back(avector<Vertex>());
}
QuadMeshNode (Ref<SceneGraph::QuadMeshNode> imesh, const Transformations& spaces)
: Node(true),
time_range(imesh->time_range),
positions(transformMSMBlurBuffer(imesh->positions,spaces)),
normals(transformMSMBlurNormalBuffer(imesh->normals,spaces)),
texcoords(imesh->texcoords), quads(imesh->quads), material(imesh->material) {}
@@ -772,6 +780,7 @@ namespace embree
virtual void resetInDegree();
public:
BBox1f time_range;
std::vector<avector<Vertex>> positions;
std::vector<avector<Vertex>> normals;
std::vector<Vec2f> texcoords;
@@ -784,8 +793,9 @@ namespace embree
{
typedef Vec3fa Vertex;
SubdivMeshNode (Ref<MaterialNode> material, size_t numTimeSteps = 0)
: Node(true),
SubdivMeshNode (Ref<MaterialNode> material, const BBox1f time_range = BBox1f(0,1), size_t numTimeSteps = 0)
: Node(true),
time_range(time_range),
position_subdiv_mode(RTC_SUBDIVISION_MODE_SMOOTH_BOUNDARY),
normal_subdiv_mode(RTC_SUBDIVISION_MODE_SMOOTH_BOUNDARY),
texcoord_subdiv_mode(RTC_SUBDIVISION_MODE_SMOOTH_BOUNDARY),
@@ -793,13 +803,12 @@ namespace embree
{
for (size_t i=0; i<numTimeSteps; i++)
positions.push_back(avector<Vertex>());
for (size_t i=0; i<numTimeSteps; i++)
normals.push_back(avector<Vertex>());
zero_pad_arrays();
}
SubdivMeshNode (Ref<SceneGraph::SubdivMeshNode> imesh, const Transformations& spaces)
: Node(true),
: Node(true),
time_range(imesh->time_range),
positions(transformMSMBlurBuffer(imesh->positions,spaces)),
normals(transformMSMBlurNormalBuffer(imesh->normals,spaces)),
texcoords(imesh->texcoords),
@@ -886,6 +895,7 @@ namespace embree
virtual void resetInDegree();
public:
BBox1f time_range; //!< geometry time range for motion blur
std::vector<avector<Vertex>> positions; //!< vertex positions for multiple timesteps
std::vector<avector<Vertex>> normals; //!< vertex normals
std::vector<Vec2f> texcoords; //!< face texture coordinates
@@ -921,21 +931,26 @@ namespace embree
};
public:
HairSetNode (RTCGeometryType type, Ref<MaterialNode> material, size_t numTimeSteps = 0)
: Node(true), type(type), material(material), tessellation_rate(4)
HairSetNode (RTCGeometryType type, Ref<MaterialNode> material, const BBox1f time_range = BBox1f(0,1), size_t numTimeSteps = 0)
: Node(true), time_range(time_range), type(type), material(material), tessellation_rate(4)
{
for (size_t i=0; i<numTimeSteps; i++)
positions.push_back(avector<Vertex>());
}
HairSetNode (const avector<Vertex>& positions_in, const std::vector<Hair>& hairs, Ref<MaterialNode> material, RTCGeometryType type)
: Node(true), type(type), hairs(hairs), material(material), tessellation_rate(4)
: Node(true), time_range(0.0f,1.0f), type(type), hairs(hairs), material(material), tessellation_rate(4)
{
positions.push_back(positions_in);
}
HairSetNode (Ref<SceneGraph::HairSetNode> imesh, const Transformations& spaces)
: Node(true), type(imesh->type), positions(transformMSMBlurBuffer(imesh->positions,spaces)), normals(transformMSMBlurNormalBuffer(imesh->normals,spaces)), tangents(transformMSMBlurVectorBuffer(imesh->tangents,spaces)),
: Node(true),
time_range(imesh->time_range),
type(imesh->type),
positions(transformMSMBlurBuffer(imesh->positions,spaces)),
normals(transformMSMBlurNormalBuffer(imesh->normals,spaces)),
tangents(transformMSMBlurVectorBuffer(imesh->tangents,spaces)),
hairs(imesh->hairs), flags(imesh->flags), material(imesh->material), tessellation_rate(imesh->tessellation_rate) {}
virtual void setMaterial(Ref<MaterialNode> material) {
@@ -991,6 +1006,7 @@ namespace embree
virtual void resetInDegree();
public:
BBox1f time_range; //!< geometry time range for motion blur
RTCGeometryType type; //!< type of curve
std::vector<avector<Vertex>> positions; //!< hair control points (x,y,z,r) for multiple timesteps
std::vector<avector<Vertex>> normals; //!< hair control normals (nx,ny,nz) for multiple timesteps
@@ -1025,8 +1041,8 @@ namespace embree
};
public:
GridMeshNode (Ref<MaterialNode> material, size_t numTimeSteps = 0)
: Node(true), material(material)
GridMeshNode (Ref<MaterialNode> material, const BBox1f time_range = BBox1f(0,1), size_t numTimeSteps = 0)
: Node(true), time_range(time_range), material(material)
{
for (size_t i=0; i<numTimeSteps; i++)
positions.push_back(avector<Vertex>());
@@ -1034,6 +1050,7 @@ namespace embree
GridMeshNode (Ref<SceneGraph::GridMeshNode> imesh, const Transformations& spaces)
: Node(true),
time_range(imesh->time_range),
positions(transformMSMBlurBuffer(imesh->positions,spaces)),
grids(imesh->grids), material(imesh->material) {}
@@ -1085,6 +1102,7 @@ namespace embree
virtual void resetInDegree();
public:
BBox1f time_range;
std::vector<avector<Vertex>> positions;
std::vector<Grid> grids;
Ref<MaterialNode> material;
+34 -10
View File
@@ -245,6 +245,7 @@ namespace embree
Ref<SceneGraph::Node> loadTriangleMesh(const Ref<XML>& xml);
Ref<SceneGraph::Node> loadQuadMesh(const Ref<XML>& xml);
Ref<SceneGraph::Node> loadGridMesh(const Ref<XML>& xml);
Ref<SceneGraph::Node> loadSubdivMesh(const Ref<XML>& xml);
Ref<SceneGraph::Node> loadBezierCurves(const Ref<XML>& xml, SceneGraph::CurveSubtype subtype); // only for compatibility
Ref<SceneGraph::Node> loadCurves(const Ref<XML>& xml, RTCGeometryType type);
@@ -898,7 +899,7 @@ namespace embree
Ref<SceneGraph::Node> XMLLoader::loadTriangleMesh(const Ref<XML>& xml)
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++)
@@ -933,15 +934,13 @@ namespace embree
Ref<SceneGraph::Node> XMLLoader::loadQuadMesh(const Ref<XML>& xml)
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material);
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++)
mesh->positions.push_back(loadVec3faArray(animation->child(i)));
} else {
auto vec = loadVec3faArray(xml->childOpt("normals"));
for (size_t i=0; i<mesh->numTimeSteps(); i++)
mesh->normals.push_back(vec);
mesh->positions.push_back(loadVec3faArray(xml->childOpt("positions")));
}
if (Ref<XML> animation = xml->childOpt("animated_normals")) {
@@ -964,6 +963,25 @@ namespace embree
return mesh.dynamicCast<SceneGraph::Node>();
}
Ref<SceneGraph::Node> XMLLoader::loadGridMesh(const Ref<XML>& xml)
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++)
mesh->positions.push_back(loadVec3faArray(animation->child(i)));
} else {
mesh->positions.push_back(loadVec3faArray(xml->childOpt("positions")));
}
std::vector<Vec4i> grids = loadVec4iArray(xml->childOpt("grids"));
for (size_t i=0; i<grids.size(); i++)
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(grids[i].x,grids[i].y,grids[i].z,grids[i].w));
mesh->verify();
return mesh.dynamicCast<SceneGraph::Node>();
}
RTCSubdivisionMode parseSubdivMode(const Ref<XML>& xml)
{
std::string subdiv_mode = xml->parm("subdiv_mode");
@@ -979,7 +997,7 @@ namespace embree
Ref<SceneGraph::Node> XMLLoader::loadSubdivMesh(const Ref<XML>& xml)
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material);
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++)
@@ -1046,7 +1064,7 @@ namespace embree
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
RTCGeometryType type = (subtype == SceneGraph::ROUND_CURVE) ? RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE : RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++)
@@ -1075,7 +1093,7 @@ namespace embree
Ref<SceneGraph::Node> XMLLoader::loadCurves(const Ref<XML>& xml, RTCGeometryType type)
{
Ref<SceneGraph::MaterialNode> material = loadMaterial(xml->child("material"));
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material);
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,BBox1f(0,1),0);
if (Ref<XML> animation = xml->childOpt("animated_positions")) {
for (size_t i=0; i<animation->size(); i++) {
@@ -1269,6 +1287,7 @@ namespace embree
else if (xml->name == "QuadLight" ) node = state.sceneMap[id] = loadQuadLight (xml);
else if (xml->name == "TriangleMesh" ) node = state.sceneMap[id] = loadTriangleMesh (xml);
else if (xml->name == "QuadMesh" ) node = state.sceneMap[id] = loadQuadMesh (xml);
else if (xml->name == "GridMesh" ) node = state.sceneMap[id] = loadGridMesh (xml);
else if (xml->name == "SubdivisionMesh" ) node = state.sceneMap[id] = loadSubdivMesh (xml);
else if (xml->name == "Hair" ) node = state.sceneMap[id] = loadBezierCurves (xml,SceneGraph::FLAT_CURVE);
else if (xml->name == "LineSegments" ) node = state.sceneMap[id] = loadCurves (xml,RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE);
@@ -1338,7 +1357,12 @@ namespace embree
else if (xml->name == "ConvertQuadsToSubdivs" ) node = state.sceneMap[id] = convert_quads_to_subdivs (loadNode(xml->child(0)));
else if (xml->name == "ConvertBezierToLines" ) node = state.sceneMap[id] = convert_bezier_to_lines (loadNode(xml->child(0)));
else if (xml->name == "ConvertHairToCurves" ) node = state.sceneMap[id] = convert_flat_to_round_curves(loadNode(xml->child(0)));
else if (xml->name == "Flatten" ) node = state.sceneMap[id] = flatten (loadNode(xml->child(0)), SceneGraph::INSTANCING_NONE);
else if (xml->name == "Flatten" ) node = state.sceneMap[id] = flatten(loadNode(xml->child(0)), SceneGraph::INSTANCING_NONE);
else if (xml->name == "TimeRange" ) {
const Vec2f time_range = xml->parm_Vec2f("time");
node = state.sceneMap[id] = loadNode(xml->child(0));
set_time_range(node,BBox1f(time_range.x,time_range.y));
}
else THROW_RUNTIME_ERROR(xml->loc.str()+": unknown tag: "+xml->name);
@@ -1363,7 +1387,7 @@ namespace embree
{
size_t matid = xml->child("materiallist")->body[0].Int();
Ref<SceneGraph::MaterialNode> material = id2material.at(matid);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material);
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),0);
mesh->positions.push_back(loadVec3faArray(xml->childOpt("vertex")));
mesh->normals.push_back(loadVec3faArray(xml->childOpt("normal")));
+5 -1
View File
@@ -29,7 +29,11 @@ namespace embree
{
while (cin->peek() == Token::Sym("<!--")) {
cin->drop();
while (cin->peek() != Token::Sym("-->")) cin->drop();
while (cin->peek() != Token::Sym("-->")) {
if (cin->peek() == Token::Eof())
THROW_RUNTIME_ERROR(cin->get().Location().str()+": --> expected");
cin->drop();
}
cin->drop();
}
}
+7 -2
View File
@@ -43,11 +43,16 @@ namespace embree
if (i == parms.end()) return ""; else return i->second;
}
Vec2f parm_Vec2f(const std::string& parmID) const {
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
return string_to_Vec2f(i->second);
}
Vec3fa parm_Vec3fa(const std::string& parmID) const {
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
const Vec3f p = string_to_Vec3f(i->second);
return Vec3fa(p);
return Vec3fa(string_to_Vec3f(i->second));
}
float parm_float(const std::string& parmID) const {
+20 -1
View File
@@ -140,6 +140,8 @@ namespace embree
texcoords = in->texcoords.data();
triangles = (ISPCTriangle*) in->triangles.data();
startTime = in->time_range.lower;
endTime = in->time_range.upper;
numTimeSteps = (unsigned) in->numTimeSteps();
numVertices = (unsigned) in->numVertices();
numTriangles = (unsigned) in->numPrimitives();
@@ -166,6 +168,8 @@ namespace embree
texcoords = in->texcoords.data();
quads = (ISPCQuad*) in->quads.data();
startTime = in->time_range.lower;
endTime = in->time_range.upper;
numTimeSteps = (unsigned) in->numTimeSteps();
numVertices = (unsigned) in->numVertices();
numQuads = (unsigned) in->numPrimitives();
@@ -186,6 +190,8 @@ namespace embree
positions[i] = in->positions[i].data();
grids = (ISPCGrid*) in->grids.data();
startTime = in->time_range.lower;
endTime = in->time_range.upper;
numTimeSteps = (unsigned) in->numTimeSteps();
numVertices = (unsigned) in->numVertices();
numGrids = (unsigned) in->numPrimitives();
@@ -223,6 +229,8 @@ namespace embree
edge_crease_weights = in->edge_crease_weights.data();
vertex_creases = in->vertex_creases.data();
vertex_crease_weights = in->vertex_crease_weights.data();
startTime = in->time_range.lower;
endTime = in->time_range.upper;
numTimeSteps = unsigned(in->numTimeSteps());
numVertices = unsigned(in->numPositions());
numFaces = unsigned(in->numPrimitives());
@@ -275,6 +283,8 @@ namespace embree
hairs = (ISPCHair*) in->hairs.data();
flags = (unsigned char*)in->flags.data();
startTime = in->time_range.lower;
endTime = in->time_range.upper;
numTimeSteps = (unsigned) in->numTimeSteps();
numVertices = (unsigned) in->numVertices();
numHairs = (unsigned)in->numPrimitives();
@@ -294,6 +304,8 @@ namespace embree
spaces = (AffineSpace3fa*) alignedMalloc(in->spaces.size()*sizeof(AffineSpace3fa),16);
geom.geomID = scene->geometryID(in->child);
child = ISPCScene::convertGeometry(scene,in->child);
startTime = in->spaces.time_range.lower;
endTime = in->spaces.time_range.upper;
for (size_t i=0; i<numTimeSteps; i++)
spaces[i] = in->spaces[i];
}
@@ -350,6 +362,7 @@ namespace embree
{
RTCGeometry geom = rtcNewGeometry (device, RTC_GEOMETRY_TYPE_TRIANGLE);
rtcSetGeometryTimeStepCount(geom,mesh->numTimeSteps);
rtcSetGeometryTimeRange(geom,mesh->startTime,mesh->endTime);
rtcSetGeometryBuildQuality(geom, quality);
for (unsigned int t=0; t<mesh->numTimeSteps; t++) {
rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT3, mesh->positions[t], 0, sizeof(Vec3fa), mesh->numVertices);
@@ -367,6 +380,7 @@ namespace embree
{
RTCGeometry geom = rtcNewGeometry (device, RTC_GEOMETRY_TYPE_QUAD);
rtcSetGeometryTimeStepCount(geom,mesh->numTimeSteps);
rtcSetGeometryTimeRange(geom,mesh->startTime,mesh->endTime);
rtcSetGeometryBuildQuality(geom, quality);
for (unsigned int t=0; t<mesh->numTimeSteps; t++) {
rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT3, mesh->positions[t], 0, sizeof(Vec3fa), mesh->numVertices);
@@ -384,6 +398,7 @@ namespace embree
{
RTCGeometry geom = rtcNewGeometry (device, RTC_GEOMETRY_TYPE_GRID);
rtcSetGeometryTimeStepCount(geom,mesh->numTimeSteps);
rtcSetGeometryTimeRange(geom,mesh->startTime,mesh->endTime);
rtcSetGeometryBuildQuality(geom, quality);
for (unsigned int t=0; t<mesh->numTimeSteps; t++) {
rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT3, mesh->positions[t], 0, sizeof(Vec3fa), mesh->numVertices);
@@ -401,6 +416,7 @@ namespace embree
{
RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_SUBDIVISION);
rtcSetGeometryTimeStepCount(geom,mesh->numTimeSteps);
rtcSetGeometryTimeRange(geom,mesh->startTime,mesh->endTime);
rtcSetGeometryBuildQuality(geom, quality);
for (unsigned int i=0; i<mesh->numEdges; i++) mesh->subdivlevel[i] = FIXED_EDGE_TESSELLATION_VALUE;
for (unsigned int t=0; t<mesh->numTimeSteps; t++) {
@@ -455,6 +471,7 @@ namespace embree
{
RTCGeometry geom = rtcNewGeometry(device, mesh->type);
rtcSetGeometryTimeStepCount(geom,mesh->numTimeSteps);
rtcSetGeometryTimeRange(geom,mesh->startTime,mesh->endTime);
rtcSetGeometryBuildQuality(geom, quality);
for (unsigned int t=0; t<mesh->numTimeSteps; t++) {
@@ -522,10 +539,12 @@ namespace embree
instance->geom.geomID = geomID;
return geomID;
}
else {
else
{
RTCGeometry geom = rtcNewGeometry (device, RTC_GEOMETRY_TYPE_INSTANCE);
rtcSetGeometryInstancedScene(geom,scene_inst);
rtcSetGeometryTimeStepCount(geom,instance->numTimeSteps);
rtcSetGeometryTimeRange(geom,instance->startTime,instance->endTime);
for (size_t t=0; t<instance->numTimeSteps; t++)
rtcSetGeometryTransform(geom,(unsigned int)t,RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR,&instance->spaces[t].l.vx.x);
rtcCommitGeometry(geom);
+16 -4
View File
@@ -115,7 +115,9 @@ namespace embree
Vec3fa** normals; //!< vertex normal array
Vec2f* texcoords; //!< vertex texcoord array
ISPCTriangle* triangles; //!< list of triangles
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numTriangles;
@@ -139,7 +141,9 @@ namespace embree
Vec3fa** normals; //!< vertex normal array
Vec2f* texcoords; //!< vertex texcoord array
ISPCQuad* quads; //!< list of quads
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numQuads;
@@ -176,7 +180,9 @@ namespace embree
unsigned int* vertex_creases; //!< indices of vertex creases
float* vertex_crease_weights; //!< weight for each vertex crease
unsigned int* face_offsets;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numFaces;
@@ -212,6 +218,8 @@ namespace embree
uint8* flags; //!< end cap flags per segment
#endif
RTCGeometryType type;
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numHairs;
@@ -235,7 +243,9 @@ namespace embree
ISPCGeometry geom;
Vec3fa** positions; //!< vertex position array
ISPCGrid* grids; //!< list of quads
float startTime;
float endTime;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numGrids;
@@ -257,6 +267,8 @@ namespace embree
ISPCGeometry geom;
ISPCGeometry* child;
float startTime;
float endTime;
unsigned int numTimeSteps;
AffineSpace3fa* spaces;
};
+13
View File
@@ -916,6 +916,19 @@ namespace embree
glfwSwapBuffers(window);
#ifdef __APPLE__
// work around glfw issue #1334
// https://github.com/glfw/glfw/issues/1334
static bool macMoved = false;
if (!macMoved) {
int x, y;
glfwGetWindowPos(window, &x, &y);
glfwSetWindowPos(window, ++x, y);
macMoved = true;
}
#endif
double dt1 = getSeconds()-t0;
avg_frame_time.add(dt1);
+41 -40
View File
@@ -49,9 +49,9 @@ Vec3fa renderPixelEyeLight(float x, float y, const ISPCCamera& camera, RayStats&
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -108,9 +108,9 @@ Vec3fa renderPixelOcclusion(float x, float y, const ISPCCamera& camera, RayStats
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcOccluded1(g_scene,&context,RTCRay_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcOccluded1(g_scene,&context.context,RTCRay_(ray));
RayStats_addRay(stats);
/* return black if nothing hit */
@@ -165,9 +165,9 @@ Vec3fa renderPixelUV(float x, float y, const ISPCCamera& camera, RayStats& stats
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -222,9 +222,9 @@ Vec3fa renderPixelTexCoords(float x, float y, const ISPCCamera& camera, RayStats
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -292,9 +292,9 @@ Vec3fa renderPixelNg(float x, float y, const ISPCCamera& camera, RayStats& stats
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -357,9 +357,9 @@ Vec3fa renderPixelGeomID(float x, float y, const ISPCCamera& camera, RayStats& s
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -412,9 +412,9 @@ Vec3fa renderPixelGeomIDPrimID(float x, float y, const ISPCCamera& camera, RaySt
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -468,9 +468,9 @@ Vec3fa renderPixelCycles(float x, float y, const ISPCCamera& camera, RayStats& s
/* intersect ray with scene */
int64_t c0 = get_tsc();
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
int64_t c1 = get_tsc();
RayStats_addRay(stats);
@@ -523,15 +523,16 @@ Vec3fa renderPixelAmbientOcclusion(float x, float y, const ISPCCamera& camera, R
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f);
Vec3fa Ng = normalize(ray.Ng);
Vec3fa Nf = faceforward(Ng,ray.dir,Ng);
Vec3fa col = Vec3fa(min(1.f,.3f+.8f*abs(dot(Ng,normalize(ray.dir)))));
/* calculate hit point */
@@ -544,12 +545,13 @@ Vec3fa renderPixelAmbientOcclusion(float x, float y, const ISPCCamera& camera, R
RandomSampler_init(sampler, (int)x, (int)y, 0);
for (int i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++)
{
Vec3fa dir = cosineSampleHemisphere(RandomSampler_get2D(sampler));
Vec2f sample = RandomSampler_get2D(sampler);
Sample3f dir = cosineSampleHemisphere(sample.x,sample.y,Nf);
/* initialize shadow ray */
Ray shadow;
shadow.org = hitPos;
shadow.dir = dir;
shadow.dir = dir.v;
shadow.tnear() = 0.001f;
shadow.tfar = inf;
shadow.geomID = RTC_INVALID_GEOMETRY_ID;
@@ -558,14 +560,13 @@ Vec3fa renderPixelAmbientOcclusion(float x, float y, const ISPCCamera& camera, R
shadow.time() = g_debug;
/* trace shadow ray */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcOccluded1(g_scene,&context,RTCRay_(shadow));
//rtcIntersect1(g_scene,&context,shadow);
IntersectContext context;
InitIntersectionContext(&context);
rtcOccluded1(g_scene,&context.context,RTCRay_(shadow));
RayStats_addShadowRay(stats);
/* add light contribution */
if (shadow.geomID == RTC_INVALID_GEOMETRY_ID)
if (shadow.tfar >=0.0f)
intensity += 1.0f;
}
intensity *= 1.0f/AMBIENT_OCCLUSION_SAMPLES;
@@ -620,9 +621,9 @@ Vec3fa renderPixelDifferentials(float x, float y, const ISPCCamera& camera, RayS
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -735,9 +736,9 @@ extern "C" bool device_pick(const float x,
ray.time() = g_debug;
/* intersect ray with scene */
RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit1_(ray));
IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit1_(ray));
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
@@ -119,22 +119,6 @@ unsigned int getNumHWThreads();
#define MAYBE_UNUSED
#endif
struct Sample3f
{
Vec3fa v;
float pdf;
};
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
/* draws progress bar */
extern "C" void progressStart();
extern "C" bool progressMonitor(void* ptr, const double n);
+41 -40
View File
@@ -47,9 +47,9 @@ Vec3f renderPixelEyeLight(float x, float y, const uniform ISPCCamera& camera, un
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -106,9 +106,9 @@ Vec3f renderPixelOcclusion(float x, float y, const uniform ISPCCamera& camera, u
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcOccludedV(g_scene,&context,RTCRay_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcOccludedV(g_scene,&context.context,RTCRay_(ray));
RayStats_addRay(stats);
/* return black if nothing hit */
@@ -163,9 +163,9 @@ Vec3f renderPixelUV(float x, float y, const uniform ISPCCamera& camera, uniform
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -220,9 +220,9 @@ Vec3f renderPixelTexCoords(float x, float y, const uniform ISPCCamera& camera, u
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -290,9 +290,9 @@ Vec3f renderPixelNg(float x, float y, const uniform ISPCCamera& camera, uniform
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -355,9 +355,9 @@ Vec3f renderPixelGeomID(float x, float y, const uniform ISPCCamera& camera, unif
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -410,9 +410,9 @@ Vec3f renderPixelGeomIDPrimID(float x, float y, const uniform ISPCCamera& camera
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -466,9 +466,9 @@ Vec3f renderPixelCycles(float x, float y, const uniform ISPCCamera& camera, unif
/* intersect ray with scene */
uniform int64 c0 = get_tsc();
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
uniform int64 c1 = get_tsc();
RayStats_addRay(stats);
@@ -521,15 +521,16 @@ Vec3f renderPixelAmbientOcclusion(float x, float y, const uniform ISPCCamera& ca
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return make_Vec3f(0.0f);
Vec3f Ng = normalize(ray.Ng);
Vec3f Nf = faceforward(Ng,ray.dir,Ng);
Vec3f col = make_Vec3f(min(1.f,.3f+.8f*abs(dot(Ng,normalize(ray.dir)))));
/* calculate hit point */
@@ -542,12 +543,13 @@ Vec3f renderPixelAmbientOcclusion(float x, float y, const uniform ISPCCamera& ca
RandomSampler_init(sampler, (int)x, (int)y, 0);
for (uniform int i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++)
{
Vec3f dir = cosineSampleHemisphere(RandomSampler_get2D(sampler));
Vec2f sample = RandomSampler_get2D(sampler);
Sample3f dir = cosineSampleHemisphere(sample.x,sample.y,Nf);
/* initialize shadow ray */
Ray shadow;
shadow.org = hitPos;
shadow.dir = dir;
shadow.dir = dir.v;
shadow.tnear = 0.001f;
shadow.tfar = inf;
shadow.geomID = RTC_INVALID_GEOMETRY_ID;
@@ -556,14 +558,13 @@ Vec3f renderPixelAmbientOcclusion(float x, float y, const uniform ISPCCamera& ca
shadow.time = g_debug;
/* trace shadow ray */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcOccludedV(g_scene,&context,RTCRay_(shadow));
//rtcIntersectV(g_scene,&context,shadow);
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcOccludedV(g_scene,&context.context,RTCRay_(shadow));
RayStats_addShadowRay(stats);
/* add light contribution */
if (shadow.geomID == RTC_INVALID_GEOMETRY_ID)
if (shadow.tfar >= 0.0f)
intensity += 1.0f;
}
intensity *= 1.0f/AMBIENT_OCCLUSION_SAMPLES;
@@ -618,9 +619,9 @@ Vec3f renderPixelDifferentials(float x, float y, const uniform ISPCCamera& camer
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersectV(g_scene,&context,RTCRayHit_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersectV(g_scene,&context.context,RTCRayHit_(ray));
RayStats_addRay(stats);
/* shade pixel */
@@ -733,9 +734,9 @@ export uniform bool device_pick(const uniform float x,
ray.time = g_debug;
/* intersect ray with scene */
uniform RTCIntersectContext context;
rtcInitIntersectContext(&context);
rtcIntersect1(g_scene,&context,RTCRayHit1_(ray));
uniform IntersectContext context;
InitIntersectionContext(&context);
rtcIntersect1(g_scene,&context.context,RTCRayHit1_(ray));
/* shade pixel */
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
@@ -117,22 +117,6 @@ uniform unsigned int getNumHWThreads();
#define MAYBE_UNUSED
#endif
struct Sample3f
{
Vec3f v;
float pdf;
};
inline uniform Sample3f make_Sample3f(const uniform Vec3f& v, const uniform float pdf) {
uniform Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3f& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
/* draws progress bar */
extern "C" unmasked void progressStart();
extern "C" unmasked uniform bool progressMonitor(void* uniform ptr, const uniform double n);
+104
View File
@@ -0,0 +1,104 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="frontview" from="278 273 -800" to="278 273 0" up="0 1 0" fov="37"/>
<PerspectiveCamera name="small_cube" from="280.1202698 284.0853577 -196.5418854" to="208.7026978 115.5031433 89.10266113" up="0 1 0" fov="45"/>
<PerspectiveCamera name="large_cube" from="420.1874695 341.1406555 -148.3326111" to="361.8019409 190.7811584 265.979126" up="0 1 0" fov="45"/>
<Group id="0">
<Group id="1">
<TriangleMesh id="2">
<material id="3">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 1 1</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions ofs="0" size="12"/>
<normals ofs="144" size="0"/>
<texcoords ofs="144" size="0"/>
<triangles ofs="144" size="6"/>
</TriangleMesh>
<TriangleMesh id="4">
<material id="3"/>
<positions ofs="216" size="4"/>
<normals ofs="264" size="0"/>
<texcoords ofs="264" size="0"/>
<triangles ofs="264" size="2"/>
</TriangleMesh>
<TriangleMesh id="5">
<material id="3"/>
<positions ofs="288" size="4"/>
<normals ofs="336" size="0"/>
<texcoords ofs="336" size="0"/>
<triangles ofs="336" size="2"/>
</TriangleMesh>
<TriangleMesh id="6">
<material id="7">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">0 1 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions ofs="360" size="4"/>
<normals ofs="408" size="0"/>
<texcoords ofs="408" size="0"/>
<triangles ofs="408" size="2"/>
</TriangleMesh>
<TriangleMesh id="8">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions ofs="432" size="4"/>
<normals ofs="480" size="0"/>
<texcoords ofs="480" size="0"/>
<triangles ofs="480" size="2"/>
</TriangleMesh>
<TimeRange time="0.5 0.75">
<Flatten>
<TransformAnimation>
<AffineSpace translate="0 0 0"/>
<AffineSpace translate="20 200 0"/>
<AffineSpace translate="40 0 100"/>
<Group>
<TriangleMesh id="10">
<material id="3"/>
<positions ofs="504" size="20"/>
<normals ofs="744" size="0"/>
<texcoords ofs="744" size="0"/>
<triangles ofs="744" size="10"/>
</TriangleMesh>
</Group>
</TransformAnimation>
</Flatten>
</TimeRange>
<TriangleMesh id="11">
<material id="3"/>
<positions ofs="864" size="4"/>
<normals ofs="912" size="0"/>
<texcoords ofs="912" size="0"/>
<triangles ofs="912" size="2"/>
</TriangleMesh>
<TriangleMesh id="12">
<material id="3"/>
<positions ofs="936" size="16"/>
<normals ofs="1128" size="0"/>
<texcoords ofs="1128" size="0"/>
<triangles ofs="1128" size="8"/>
</TriangleMesh>
</Group>
</Group>
</scene>
Binary file not shown.
+126
View File
@@ -0,0 +1,126 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="default" from="-20 8 -100" to="0 8 0" up="0 1 0" fov="20"/>
<assign type="scene">
<Curves id="cube" basis="bezier" type="flat">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions>
0.0 0.0 -1.0 0.5
0.0 0.0 0.0 0.5
0.0 0.0 0.0 0.5
0.0 0.0 +1.0 0.5
</positions>
<indices>
0
</indices>
</Curves>
</assign>
<Transform>
<AffineSpace translate="0 12 0"/>
<TimeRange time="-0.2 1.2">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-14 -4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="14 -4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 8 0"/>
<TimeRange time="-0.1 1.1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-12 -2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="12 -2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 4 0"/>
<TimeRange time="0 1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-10 0 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="10 0 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 0 0"/>
<TimeRange time="0.1 0.9">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-8 2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="8 2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -4 0"/>
<TimeRange time="0.2 0.8">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-6 4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="6 4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -8 0"/>
<TimeRange time="0.3 0.7">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-4 6 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="4 6 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -12 0"/>
<TimeRange time="0.4 0.6">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-2 8 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="2 8 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
</scene>
+157
View File
@@ -0,0 +1,157 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="default" from="-20 8 -100" to="0 8 0" up="0 1 0" fov="20"/>
<assign type="scene"> -->
<GridMesh id="cube">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions>
-1.0 -1.0 -1.0
-1.0 1.0 -1.0
1.0 -1.0 -1.0
1.0 1.0 -1.0
1.0 -1.0 -1.0
1.0 1.0 -1.0
1.0 -1.0 1.0
1.0 1.0 1.0
1.0 -1.0 1.0
1.0 1.0 1.0
-1.0 -1.0 1.0
-1.0 1.0 1.0
-1.0 -1.0 -1.0
-1.0 -1.0 1.0
-1.0 1.0 -1.0
-1.0 1.0 1.0
-1.0 1.0 -1.0
-1.0 1.0 1.0
1.0 1.0 -1.0
1.0 1.0 1.0
-1.0 -1.0 -1.0
1.0 -1.0 -1.0
-1.0 -1.0 1.0
1.0 -1.0 1.0
</positions>
<grids>
0 2 2 2
4 2 2 2
8 2 2 2
12 2 2 2
16 2 2 2
20 2 2 2
</grids>
</GridMesh>
</assign>
<Transform>
<AffineSpace translate="0 12 0"/>
<TimeRange time="-0.2 1.2">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-14 -4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="14 -4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 8 0"/>
<TimeRange time="-0.1 1.1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-12 -2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="12 -2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 4 0"/>
<TimeRange time="0 1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-10 0 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="10 0 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 0 0"/>
<TimeRange time="0.1 0.9">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-8 2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="8 2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -4 0"/>
<TimeRange time="0.2 0.8">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-6 4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="6 4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -8 0"/>
<TimeRange time="0.3 0.7">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-4 6 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="4 6 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -12 0"/>
<TimeRange time="0.4 0.6">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-2 8 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="2 8 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
</scene>
+124
View File
@@ -0,0 +1,124 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="default" from="-20 8 -100" to="0 8 0" up="0 1 0" fov="20"/>
<assign type="scene">
<LineSegments id="cube">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions>
0.0 0.0 -1.0 0.5
0.0 0.0 +1.0 0.5
</positions>
<indices>
0
</indices>
</LineSegments>
</assign>
<Transform>
<AffineSpace translate="0 12 0"/>
<TimeRange time="-0.2 1.2">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-14 -4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="14 -4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 8 0"/>
<TimeRange time="-0.1 1.1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-12 -2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="12 -2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 4 0"/>
<TimeRange time="0 1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-10 0 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="10 0 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 0 0"/>
<TimeRange time="0.1 0.9">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-8 2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="8 2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -4 0"/>
<TimeRange time="0.2 0.8">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-6 4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="6 4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -8 0"/>
<TimeRange time="0.3 0.7">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-4 6 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="4 6 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -12 0"/>
<TimeRange time="0.4 0.6">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-2 8 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="2 8 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
</scene>
+135
View File
@@ -0,0 +1,135 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="default" from="-20 8 -100" to="0 8 0" up="0 1 0" fov="20"/>
<assign type="scene">
<QuadMesh id="cube">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions>
-1.0 -1.0 -1.0
1.0 -1.0 -1.0
1.0 -1.0 1.0
-1.0 -1.0 1.0
-1.0 1.0 -1.0
1.0 1.0 -1.0
1.0 1.0 1.0
-1.0 1.0 1.0
</positions>
<indices>
0 4 5 1
1 5 6 2
2 6 7 3
0 3 7 4
4 7 6 5
0 1 2 3
</indices>
</QuadMesh>
</assign>
<Transform>
<AffineSpace translate="0 12 0"/>
<TimeRange time="-0.2 1.2">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-14 -4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="14 -4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 8 0"/>
<TimeRange time="-0.1 1.1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-12 -2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="12 -2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 4 0"/>
<TimeRange time="0 1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-10 0 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="10 0 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 0 0"/>
<TimeRange time="0.1 0.9">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-8 2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="8 2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -4 0"/>
<TimeRange time="0.2 0.8">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-6 4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="6 4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -8 0"/>
<TimeRange time="0.3 0.7">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-4 6 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="4 6 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -12 0"/>
<TimeRange time="0.4 0.6">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-2 8 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="2 8 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
</scene>
@@ -0,0 +1,135 @@
<?xml version="1.0"?>
<scene>
<PerspectiveCamera name="default" from="-20 8 -100" to="0 8 0" up="0 1 0" fov="20"/>
<assign type="scene">
<TriangleMesh id="cube">
<material id="9">
<code>"OBJ"</code>
<parameters>
<float name="d">1</float>
<float3 name="Kd">1 0 0</float3>
<float3 name="Ks">0 0 0</float3>
<float name="Ns">1</float>
</parameters>
</material>
<positions>
-1.0 -1.0 -1.0
1.0 -1.0 -1.0
1.0 -1.0 1.0
-1.0 -1.0 1.0
-1.0 1.0 -1.0
1.0 1.0 -1.0
1.0 1.0 1.0
-1.0 1.0 1.0
</positions>
<triangles>
1 4 5 0 4 1
2 5 6 1 5 2
3 6 7 2 6 3
4 3 7 0 3 4
5 7 6 4 7 5
3 1 2 0 1 3
</triangles>
</TriangleMesh>
</assign>
<Transform>
<AffineSpace translate="0 12 0"/>
<TimeRange time="-0.2 1.2">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-14 -4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="14 -4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 8 0"/>
<TimeRange time="-0.1 1.1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-12 -2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="12 -2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 4 0"/>
<TimeRange time="0 1">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-10 0 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="10 0 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 0 0"/>
<TimeRange time="0.1 0.9">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-8 2 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="8 2 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -4 0"/>
<TimeRange time="0.2 0.8">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-6 4 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="6 4 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -8 0"/>
<TimeRange time="0.3 0.7">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-4 6 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="4 6 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
<Transform>
<AffineSpace translate="0 -12 0"/>
<TimeRange time="0.4 0.6">
<Flatten>
<TransformAnimation>
<AffineSpace translate="-2 8 0"/>
<AffineSpace translate="0 10 0"/>
<AffineSpace translate="2 8 0"/>
<ref id="cube"/>
</TransformAnimation>
</Flatten>
</TimeRange>
</Transform>
</scene>
@@ -107,16 +107,6 @@ inline Vec3fa sample_component2(const Vec3fa& c0, const Sample3f& wi0, const Med
}
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3fa& N)
{
Vec3fa localDir = cosineSampleHemisphere(Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
////////////////////////////////////////////////////////////////////////////////
// Minneart BRDF //
////////////////////////////////////////////////////////////////////////////////
@@ -105,16 +105,6 @@ inline Vec3f sample_component2(const Vec3f& c0, const Sample3f& wi0, const Mediu
}
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3f& N)
{
Vec3f localDir = cosineSampleHemisphere(make_Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
////////////////////////////////////////////////////////////////////////////////
// Minneart BRDF //
////////////////////////////////////////////////////////////////////////////////
+2 -2
View File
@@ -1185,7 +1185,7 @@ namespace embree
for (size_t i=0; i<N; i++) gridmesh2->grids.push_back(gridmesh2->grids.back());
scene.addGeometry(quality,gridmesh2.dynamicCast<SceneGraph::Node>());
Ref<SceneGraph::SubdivMeshNode> subdivmesh = new SceneGraph::SubdivMeshNode(nullptr,1);
Ref<SceneGraph::SubdivMeshNode> subdivmesh = new SceneGraph::SubdivMeshNode(nullptr,BBox1f(0,1),1);
for (unsigned i=0; i<unsigned(N); i++) {
subdivmesh->verticesPerFace.push_back(4);
subdivmesh->position_indices.push_back(4*i+0);
@@ -1199,7 +1199,7 @@ namespace embree
}
scene.addGeometry(quality,subdivmesh.dynamicCast<SceneGraph::Node>());
Ref<SceneGraph::SubdivMeshNode> subdivmesh2 = new SceneGraph::SubdivMeshNode(nullptr,1);
Ref<SceneGraph::SubdivMeshNode> subdivmesh2 = new SceneGraph::SubdivMeshNode(nullptr,BBox1f(0,1),1);
for (unsigned i=0; i<unsigned(N); i++) {
subdivmesh2->verticesPerFace.push_back(4);
subdivmesh2->position_indices.push_back(4*i+0);
@@ -213,6 +213,11 @@ void postIntersectGeometry(const Ray& ray, DifferentialGeometry& dg, ISPCGeometr
ISPCQuadMesh* mesh = (ISPCQuadMesh*) geometry;
materialID = mesh->geom.materialID;
}
else if (geometry->type == GRID_MESH)
{
ISPCGridMesh* mesh = (ISPCGridMesh*) geometry;
materialID = mesh->geom.materialID;
}
else if (geometry->type == SUBDIV_MESH)
{
ISPCSubdivMesh* mesh = (ISPCSubdivMesh*) geometry;
@@ -203,6 +203,11 @@ void postIntersectGeometry(const Ray& ray, DifferentialGeometry& dg, uniform ISP
uniform ISPCQuadMesh* uniform mesh = (uniform ISPCQuadMesh* uniform) geometry;
materialID = mesh->geom.materialID;
}
else if (geometry->type == GRID_MESH)
{
uniform ISPCGridMesh* uniform mesh = (uniform ISPCGridMesh* uniform) geometry;
materialID = mesh->geom.materialID;
}
else if (geometry->type == SUBDIV_MESH)
{
uniform ISPCSubdivMesh* uniform mesh = (uniform ISPCSubdivMesh* uniform) geometry;