Compare commits
64
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86dbc8a437 | ||
|
|
4c93274a31 | ||
|
|
bd7ea15f50 | ||
|
|
1df9591a8c | ||
|
|
23753277fa | ||
|
|
95053e8c6e | ||
|
|
0ff0a6909b | ||
|
|
40e445ade8 | ||
|
|
8c08b5c5b5 | ||
|
|
a07e9b0c5c | ||
|
|
0f4f821f76 | ||
|
|
cf4d9e9f62 | ||
|
|
d25f7b0ac2 | ||
|
|
15caf3fd1b | ||
|
|
0eb47c2c6b | ||
|
|
9de546d581 | ||
|
|
33bd19d2a3 | ||
|
|
4e1a7741fb | ||
|
|
e2f4851405 | ||
|
|
17a17f7e18 | ||
|
|
b27a31f572 | ||
|
|
a7772b05aa | ||
|
|
03f24bbba5 | ||
|
|
d2db02fa10 | ||
|
|
80c0fae902 | ||
|
|
fd6eca502f | ||
|
|
a1c750b5a2 | ||
|
|
226f9e1fb5 | ||
|
|
ef9dd1951d | ||
|
|
a6527de9c9 | ||
|
|
9805370657 | ||
|
|
ff669ab8f4 | ||
|
|
4efa364c7b | ||
|
|
ca932f7669 | ||
|
|
7297e6ffff | ||
|
|
b04f338936 | ||
|
|
bb4cd86ea4 | ||
|
|
ba404619cc | ||
|
|
a88881677e | ||
|
|
7b7c88337d | ||
|
|
a9b96ac13f | ||
|
|
0e27f93cb2 | ||
|
|
4e725e928b | ||
|
|
d9fd88e841 | ||
|
|
abf293aa0a | ||
|
|
b71f37e1f6 | ||
|
|
0eabcdddd3 | ||
|
|
7b8fa2e8a2 | ||
|
|
a72873c854 | ||
|
|
d5e09d228d | ||
|
|
60b0c0154f | ||
|
|
5a7230da1f | ||
|
|
a8dc2540de | ||
|
|
03f654c62e | ||
|
|
7aeb056b32 | ||
|
|
4262431328 | ||
|
|
11d5e26d82 | ||
|
|
3ae221bf73 | ||
|
|
f3b787a0ea | ||
|
|
0ec8f6a299 | ||
|
|
4be6966f63 | ||
|
|
49fab5e8e0 | ||
|
|
a8ee444842 | ||
|
|
d710ab6245 |
+4
-4
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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")
|
||||
|
||||
@@ -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}
|
||||
```
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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}
|
||||
```
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -44,4 +44,4 @@ On failure an error code is set that can be queried using
|
||||
|
||||
#### SEE ALSO
|
||||
|
||||
[rtcNewGeometry]
|
||||
[rtcNewGeometry], [rtcSetGeometryTimeRange]
|
||||
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) !!
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Binary file not shown.
+4
-4
@@ -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)
|
||||
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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 //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user