1
1

Compare commits

..

352 Commits

Author SHA1 Message Date
a640587e25 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-17 20:20:22 +01:00
892637f60a Merge branch 'master' into temp-openxr-blenderside 2020-03-17 20:19:58 +01:00
c333f57603 Ghost: Ghost-XR API to abstract away and access OpenXR functionality
Extends Ghost to include an abstraction for OpenXR, which I refer to as
Ghost-XR. Such an API is the base for the following commit, which introduces VR
support to Blender.

Main features:
* Simple and high-level interface for Blender specific code to call.
* Extensible for muliple graphics backends, currently OpenGL and a DirectX
  compatibility layer are supported.
* Carefully designed error handling strategy allowing Blender to handle errors
  gracefully and with useful error messages.
* OpenXR extension and API-layer management.
* OpenXR session management.
* Basic OpenXR event management.
* Debug utilities for Ghost-XR and OpenXR

For more information on this API, check
https://wiki.blender.org/wiki/Source/Interface/XR.

Reviewed by: Brecht Van Lommel

Differential Revision: https://developer.blender.org/D6188
2020-03-17 20:10:57 +01:00
99eb95337f Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-17 16:40:07 +01:00
5d30598e3b Make it obvious that the DRW context getters are not for general use 2020-03-17 16:28:29 +01:00
1a7135b12f Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-16 22:07:02 +01:00
ae14649583 Fix comment being printed to console in Windows batch file 2020-03-16 22:00:36 +01:00
a75a79272e Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-16 18:15:10 +01:00
ddbbd9928e Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-16 18:14:24 +01:00
d2ef342b2a Merge branch 'master' into temp-openxr-ghostxr 2020-03-16 18:13:37 +01:00
b86be9b214 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-12 15:58:03 +01:00
cb6cec904f Merge branch 'master' into temp-openxr-ghostxr 2020-03-12 15:55:48 +01:00
dd8ef89633 Remove leftover from merge conflict 2020-03-11 16:31:50 +01:00
5cca2f041d Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-11 16:28:43 +01:00
00f83ec125 Cleanup and correct wrong bpy.app.build_options usage 2020-03-11 16:27:48 +01:00
a2d04deda7 Remove in-place call to create reports-popup
To be replaced by D7113.
2020-03-11 15:34:49 +01:00
8f327fb070 Cleanup: Add comments on GPU data and Ghost context usage 2020-03-11 14:14:27 +01:00
f8c3ccf398 Add more info to blender_oculus batch file 2020-03-11 12:35:18 +01:00
7c11e45f5f Cleanup: Address various review comments 2020-03-11 12:34:23 +01:00
792335cfab Cleanup: Run clang-format on all affected files 2020-03-11 11:26:42 +01:00
b381eba6c7 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-11 11:26:05 +01:00
066d755e47 Cleanup: Clang-format 2020-03-11 11:25:49 +01:00
f2018ba492 Cleanup: Remove unused Ghost window function 2020-03-11 11:23:59 +01:00
8126e4ac14 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-10 18:23:46 +01:00
cfa4302570 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-10 18:23:32 +01:00
e7ceb041cf Merge branch 'master' into temp-openxr-ghostxr 2020-03-10 18:22:40 +01:00
Julian Eisel
c02ba3653a Color transforms were fixed in Windows MR -> disable our workaround 2020-03-10 16:48:18 +01:00
9abf5ba1d5 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-10 16:34:26 +01:00
1cc81d39c4 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-10 16:21:15 +01:00
e38cd1741e Remove old files/changes, git keeps bringing them back... 2020-03-10 16:11:44 +01:00
27bc3388da Minor cleanup: Avoid forward declaration 2020-03-10 16:05:06 +01:00
8b8142c13a Remove obscure unique_oxr_ptr, implement alternative RAII for swapchain
Add an own class for the swapchain, through which we can ensure correct
RAII resource management.
2020-03-10 16:00:06 +01:00
d60c71f33d Cleanup: Avoid macros, don't print source location for errors 2020-03-09 18:58:20 +01:00
916efac0c8 Cleanup: Address various review comments 2020-03-09 18:47:31 +01:00
ef20e1d378 Add comments to C-API function declarations 2020-03-09 18:37:16 +01:00
f73a6c517c Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-09 11:56:13 +01:00
6e13062ddb Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-09 11:55:47 +01:00
73791a755a Merge branch 'master' into temp-openxr-ghostxr 2020-03-09 11:31:48 +01:00
Julian Eisel
28321b064a Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-05 12:40:18 +01:00
Julian Eisel
10d563baf4 Add XR_ prefix like now in master 2020-03-05 12:36:40 +01:00
Julian Eisel
812c4f45f5 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-05 12:32:54 +01:00
Julian Eisel
75163f2a7d Add XR_ prefix like now in master 2020-03-05 12:20:27 +01:00
Julian Eisel
3c0c28afe1 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-03-05 12:11:16 +01:00
Julian Eisel
4ecea3dd3e Merge branch 'master' into temp-openxr-directx 2020-03-05 12:10:58 +01:00
Julian Eisel
68cec61dae Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-03-02 15:30:09 +01:00
Julian Eisel
c822556e27 Update oculus.json file for the Oculus runtime on Windows 2020-03-02 15:12:53 +01:00
Julian Eisel
e62a012f90 Fix compiler warning on Linux, swapping with wrong type 2020-03-02 14:51:20 +01:00
Julian Eisel
be7b41df3f Bring back vertically mirrored drawing for DirectX compatibility 2020-03-02 14:51:12 +01:00
Julian Eisel
6f977c5e6d Always do versioning code, even with WITH_OPENXR disabled 2020-03-02 14:41:56 +01:00
Julian Eisel
a74af5f6f0 Always generate XR-RNA, even with WITH_OPENXR disabled 2020-03-02 14:39:12 +01:00
Julian Eisel
3e41ea03be Cleanup: Move struct forward declaration to top of header 2020-03-02 14:31:01 +01:00
Julian Eisel
489da13b94 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-03-02 12:59:24 +01:00
Julian Eisel
f9a3a42412 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-03-02 12:52:41 +01:00
Julian Eisel
202623419e Use GL_NEAREST as interpolation mode for framebuffer blitting 2020-03-02 12:41:01 +01:00
Julian Eisel
49f7848589 Avoid clearing render-target on each redraw in release builds 2020-03-02 12:40:14 +01:00
Julian Eisel
6fda295034 Add comment on DirectX device debugging 2020-03-02 12:39:38 +01:00
Julian Eisel
2b7e94e35e Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-03-02 12:07:58 +01:00
Julian Eisel
65ceb8ee5d Don't attempt to force enable WITH_OPENXR on macOS 2020-03-02 11:01:26 +01:00
Julian Eisel
9b5a1edbc4 Remove unnecessary CMake search hints 2020-03-02 11:00:41 +01:00
Julian Eisel
6cceecb82f Mark WITH_OPENXR as advanced on macOS 2020-03-02 11:00:01 +01:00
Julian Eisel
166c1f9a92 Merge branch 'master' into temp-openxr-buildstuff 2020-03-02 10:46:59 +01:00
Julian Eisel
3da9ecc6c1 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-26 21:19:59 +01:00
Julian Eisel
0f979f3388 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-02-26 21:19:35 +01:00
Julian Eisel
72ad66b101 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-02-26 21:19:23 +01:00
Julian Eisel
f25a348915 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-02-26 21:19:09 +01:00
Julian Eisel
af00df3469 Update OpenXR SDK dependency to version 1.0.6
Also fix a merge error in install_deps.sh
2020-02-26 21:18:10 +01:00
Julian Eisel
80c6f6eb4e Merge branch 'master' into temp-openxr-buildstuff 2020-02-26 21:17:04 +01:00
Julian Eisel
62db972f0f Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-25 14:43:41 +01:00
Julian Eisel
e9036242fa Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-02-25 14:42:29 +01:00
Julian Eisel
83aebf759e Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-02-25 14:38:08 +01:00
Julian Eisel
5169f9e975 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-02-25 14:37:52 +01:00
Julian Eisel
d9c05e6997 Merge branch 'master' into temp-openxr-buildstuff 2020-02-25 14:36:28 +01:00
Julian Eisel
404cc8d1fc Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-20 12:56:11 +01:00
Julian Eisel
af928a2fb1 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-02-20 12:53:03 +01:00
Julian Eisel
b1c9434332 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-02-20 12:51:46 +01:00
Julian Eisel
4c2ec7c5ec Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-02-20 12:51:35 +01:00
Julian Eisel
79069884b1 Merge branch 'master' into temp-openxr-buildstuff 2020-02-20 12:51:09 +01:00
Julian Eisel
7254d1ae49 Merge branch 'master' into temp-openxr-buildstuff 2020-02-20 11:16:17 +01:00
Julian Eisel
a18c254c6d Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-17 16:57:21 +01:00
Julian Eisel
27bbbc9c57 Remove own GPUViewport and GPUContext binding
Draw-manager handles these as needed now, so we can remove this.
2020-02-17 16:53:56 +01:00
Julian Eisel
6dbe2d781d Don't create framebuffer for VR view, re-use GPUViewport one 2020-02-17 16:21:28 +01:00
Julian Eisel
19f3fdad97 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-17 12:21:00 +01:00
Julian Eisel
8d5996595f Fix compile errors and broken drawing after changes in master
There are still some issues left after the changes in master:
* Some optimizations need to be redone differently
* Color-space handling needs to be redone differently
* Upside-down drawing is broken
2020-02-17 12:15:42 +01:00
Julian Eisel
47baf42e2c Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside
This will currently fail to compile. Fixes upcoming.
2020-02-17 11:29:17 +01:00
Julian Eisel
cdfe5449df Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-02-17 11:04:02 +01:00
Julian Eisel
f0786dfc52 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-02-17 11:03:39 +01:00
Julian Eisel
de2d03ace9 Merge branch 'master' into temp-openxr-buildstuff 2020-02-17 11:01:47 +01:00
Julian Eisel
0a27ab2e93 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-02-05 14:38:19 +01:00
Julian Eisel
d930ff7f4f Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-02-05 14:37:59 +01:00
Julian Eisel
f3e9351111 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-02-05 14:37:45 +01:00
Julian Eisel
2a259497ae Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-02-05 14:37:30 +01:00
Julian Eisel
eecf3021d7 Merge branch 'master' into temp-openxr-buildstuff 2020-02-05 14:37:09 +01:00
Julian Eisel
0173800572 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-01-24 11:25:54 +01:00
Julian Eisel
bc38898cf4 Fix linking after recent build system changes in master 2020-01-24 11:24:34 +01:00
Julian Eisel
1a812145e0 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-01-24 11:22:04 +01:00
Julian Eisel
f430f6fa18 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-01-24 11:17:59 +01:00
Julian Eisel
2f6ebe1b99 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-01-24 11:17:43 +01:00
Julian Eisel
c706834749 Merge branch 'master' into temp-openxr-buildstuff 2020-01-24 11:17:23 +01:00
Julian Eisel
11ee2f1d09 Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2020-01-06 16:52:35 +01:00
Julian Eisel
fcc6e94897 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2020-01-06 14:59:25 +01:00
Julian Eisel
d6cce8bc8e Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2020-01-06 14:52:28 +01:00
Julian Eisel
4332e2b5fb Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2020-01-06 14:52:06 +01:00
Julian Eisel
3ff91e97d9 Merge branch 'master' into temp-openxr-buildstuff 2020-01-06 14:41:20 +01:00
Julian Eisel
06138de13a Color transforms were fixed in Windows MR -> disable our workaround 2019-11-29 12:40:55 +01:00
Julian Eisel
0c7ac28b8a SDK changed loader lib name on Windows, update for that 2019-11-28 19:05:07 +01:00
Julian Eisel
43cfa0b682 Merge branch 'master' into soc-2019-openxr 2019-11-27 15:25:47 +01:00
Julian Eisel
f426d3a002 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2019-11-27 15:25:12 +01:00
Julian Eisel
a1499f7f7d Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2019-11-27 12:26:56 +01:00
Julian Eisel
530a8d1ab1 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2019-11-27 12:24:12 +01:00
Julian Eisel
2232406394 Merge branch 'master' into temp-openxr-buildstuff 2019-11-27 12:21:32 +01:00
Julian Eisel
8f6b3d27d0 Remove files to sync with latest changes in patches 2019-11-19 15:33:30 +01:00
Julian Eisel
ffa16f677a Merge branch 'temp-openxr-blenderside' into soc-2019-openxr 2019-11-19 15:31:07 +01:00
Julian Eisel
85ccec8639 Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2019-11-19 15:30:42 +01:00
Julian Eisel
fc83dfdba1 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2019-11-19 15:29:29 +01:00
Julian Eisel
2448eb6136 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2019-11-19 15:29:11 +01:00
Julian Eisel
90df65892f Merge branch 'master' into temp-openxr-buildstuff 2019-11-19 15:28:53 +01:00
Julian Eisel
f07e361829 Update branch to include changes from split off patches 2019-11-15 11:27:46 +01:00
Julian Eisel
779b3f0cff Bring back utility batch and config file for Oculus support 2019-11-14 12:49:18 +01:00
Julian Eisel
561f4665a6 Merge branch 'master' into soc-2019-openxr 2019-11-14 12:40:20 +01:00
Julian Eisel
58f95e9e4d Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2019-11-14 12:37:10 +01:00
Julian Eisel
17121b2afd Add required OpenXR defines to Ghost CMakeLists (used to be in root one) 2019-11-14 12:35:30 +01:00
Julian Eisel
fc26797e72 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2019-11-14 12:21:47 +01:00
Julian Eisel
fa9707a712 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2019-11-14 12:17:05 +01:00
Julian Eisel
8d45b4f75c Disable XR features (and the OpenXR SDK dependency) by default on Apple 2019-11-14 12:04:02 +01:00
Julian Eisel
03ac9de0a9 Remove XR defines from top-level CMakeLists file, can be done locally 2019-11-14 12:01:06 +01:00
Julian Eisel
4456dbcded Remove now unnecessary OpenXR SDK patch for Win CRT linkage 2019-11-14 11:51:39 +01:00
Julian Eisel
cc23a8c84d Merge branch 'master' into temp-openxr-buildstuff 2019-11-14 11:43:19 +01:00
Julian Eisel
120d9c91dc Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2019-11-13 17:03:05 +01:00
Julian Eisel
e1db5cc2c7 Remove CMake include unneeded after recent build system changes 2019-11-13 17:01:42 +01:00
Julian Eisel
a347ec08bc Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside 2019-11-13 13:02:32 +01:00
Julian Eisel
ee8e4b7db8 Merge branch 'temp-openxr-directx' into temp-openxr-ghostxr 2019-11-13 13:02:11 +01:00
Julian Eisel
8c7be58e72 Merge branch 'temp-openxr-buildstuff' into temp-openxr-directx 2019-11-13 13:01:39 +01:00
Julian Eisel
1b39eb1060 Merge branch 'master' into temp-openxr-buildstuff 2019-11-13 13:01:21 +01:00
Julian Eisel
0d98e665ea Core XR Support [part 1]: Add OpenXR-SDK dependency and WITH_OPENXR build option
Some points on the OpenXR-SDK dependency:
* The repository is located at https://github.com/KhronosGroup/OpenXR-SDK (Apache 2).
* We use the OpenXR loader lib from it, the headers, and some CMake utilities.
* It contains a bunch of generated files, for which the sources are in a separate repository.
* To use the injected OpenXR API-layers from the SDK (e.g. API validation layers), the SDK needs to be compiled from this other repository.
* We could use that other repo by default, but I'd rather go with the simpler solution and allow people to opt in if they want advanced dev features.
* For Windows a patch is needed to link the CRT in a compatible way.

All this is entirely untested on macOS.

Maniphest Tasks: T71365

Differential Revision: https://developer.blender.org/D6188
2019-11-13 12:57:35 +01:00
Julian Eisel
7f1fadba67 Core XR Support [part 4]: Blender-side changes (+ the remaining bits)
Changes for the higher level, more Blender specific side of the implementation.

Main additions:
* WM-XR: Layer tying Ghost-XR to the Blender specific APIs/data
* wmSurface API: drawable, non-window container (manages Ghost-OpenGL and GPU context)
* DNA/RNA for initial management of VR session settings
* Utility batch & config file for using the Oculus runtime (Windows only)

Differential Revision: https://developer.blender.org/D6193
2019-11-05 15:33:48 +01:00
Julian Eisel
8537cdc71d Core XR Support [part 3]: Ghost-XR API based on OpenXR
## Design Overview
* For code using this API, the most important object is a GHOST_XrContext handle. Through it, all API functions and internal state can be accessed/modified.
* Main responsibilities of the Ghost XR-context are to manage lifetimes of the OpenXR runtime connection (represented by XrInstance), the session and to delegate operations/data to the session.
* The OpenXR related graphics code, which is OS dependent, is managed through a `GHOST_IXrGraphicsBinding` interface, that can be implemented for the different graphics libraries supported (currently OpenGL and DirectX).
* Much of this code here has to follow the OpenXR specification and is based on the OpenXR [[https://github.com/KhronosGroup/OpenXR-SDK-Source/tree/master/src/tests/hello_xr | `hello_xr`]] implentation.
* In future we may want to take some code out of the context, e.g. extension and API layer management.
* There are runtime debugging and benchmarking options (exposed through --debug-xr and --debug-xr-time, but not as part of this patch).
* Error handling is described in a section below.

## Why have this in Ghost?

Early on, I decided to do the OpenXR level access through GHOST. Main reasons:
* OpenXR requires access to low level, OS dependent graphics lib data (e.g. see [[https://www.khronos.org/registry/OpenXR/specs/0.90/man/html/openxr.html#XrGraphicsBindingOpenGLXlibKHR| XrGraphicsBindingOpenGLXlibKHR]])
* Some C++ features appeared handy (`std::vector`, RAII + exception handling, cleaner code through object methods, etc.)
* General low level nature of the OpenXR API

After all I think much of the functionality is too high level to live in GHOST however. I would like to address this by having a separate `VAMR` (virtual + augmented + mixed reality) module, placed in `intern/`.  The main issue is getting this to work well with Ghost data, especially how to get the mentioned low level data out of Ghost.
This is something I'd like to look into again before too long, but for now I think having this in Ghost is reasonable.

## Error Handling Strategy

The error handling strategy I chose uses C++ exceptions, a controversial feature. Let me explain why I think this is reasonable here.

The strategy requirements were:
* If an error occurs, cleanly exit the VR session (or destroy the entire context), causing no resource leaks or side effects to the rest of Blender.
* Show a *useful* error message to the user.
* Don't impair readability of code too much with error handling.

Here's why I chose an exception based strategy:
* Most alternatives require early exiting functions. This early exiting has to be 'bubbled up' the call stack to the point that performs error handling. For safe code, early exit checks have to be performed everywhere and code gets really impaired by error checking. Tried this first and wasn't happy at all. Even if error handling is wrapped into macros.
* All `GHOST_Xr` resources are managed via RAII. So stack unwinding will cause them to be released cleanly whenever an exception is thrown.
* `GHOST_Xr` has a clear boundary (the Ghost C-API) with only a handful of public functions. That is the only place we need to have try-catch blocks at. (Generally, try-catch blocks at kinda random places are a bad code smell IMHO. Module boundaries are a valid place to put them.)
* Exceptions allow us to pass multiple bits of error information through mulitple layers of the call stack. This information can also be made specific with a useful error message. As of now, they conain a user error message, the OpenXR error code (if any), as well as the exact source code location the error was caught at.

So the strategy I went with works as follows:
* If a VR related error occurs within `GHOST_Xr`, throw an exception (`GHOST_XrException` currently).
* OpenXR calls are wrapped into a macro throwing an exception if the return value indicates an error.
* Useful debugging information and user messages are stored in the exceptions.
* All resources must be managed through RAII, so throwing an exception will release 'dangling' ones cleanly.
* In the GHOST C-API wrappers, the exceptions are caught and contained error information is forwarded to a custom error handling callback.
* The error handling callback is set in `wm_xr.c`, prior to creating the XR-Context, and implements clean destruction of the context.

Differential Revision: https://developer.blender.org/D6192
2019-11-05 15:00:55 +01:00
Julian Eisel
6ae2979d05 Ghost DirectX compatibility from GSoC OpenXR branch
Needed for DirectX-only OpenXR runtimes (e.g. Windows Mixed Reality).

Adds a minimal DirectX 11 Ghost context, plus some shared DirectX-OpenGL resource interface using the NV_DX_interop2 WGL extension.
I know that the current implementation fails on some systems, which is something I'll have to fix at some point. Don't know if this is a showstopper though, I can fix that in master too. For now this isn't going to be used by many people anyway. Recently I also learned that OSVR uses the same extension, see https://github.com/sensics/OSVR-RenderManager/blob/master/osvr/RenderKit/RenderManagerD3DOpenGL.cpp. Their implementation may be useful to fix the issue, according to a OSVR dev, it works quite reliably for them.

Note: Didn't actually test just this patch on Windows yet.

Differential Revision: https://developer.blender.org/D6190
2019-11-05 13:39:44 +01:00
Julian Eisel
b698a926af Add back accidentally removed CMake files
No clue how those ended up tagged as removed.
2019-11-05 12:35:44 +01:00
Julian Eisel
fac53c7bc2 Core XR Support [part 1]: Add OpenXR-SDK dependency and WITH_XR build option
Some points on the OpenXR-SDK dependency:
* The repository is located at https://github.com/KhronosGroup/OpenXR-SDK (Apache 2).
* We use the OpenXR loader lib from it, the headers, and some CMake utilities.
* It contains a bunch of generated files, for which the sources are in a separate repository.
* To use the injected OpenXR API-layers from the SDK (e.g. API validation layers), the SDK needs to be compiled from this other repository.
* We could use that other repo by default, but I'd rather go with the simpler solution and allow people to opt in if they want advanced dev features.
* I copied `presentation.cmake` and `xr_platform_defines.cmake` from the SDK. They contain logic that is not needed for us and prints at CMake generation. We could change that but figured it would also be helpful to keep the files equal to the SDK ones.
* For Windows a patch is needed to link the CRT in a compatible way.
* @LazyDodo already pushed the precompiled binaries for Windows.

All this is entirely untested on macOS.

Differential Revision: https://developer.blender.org/D6188
2019-11-05 12:32:33 +01:00
Julian Eisel
88f234e27f Merge branch 'master' into soc-2019-openxr 2019-11-05 10:30:22 +01:00
Julian Eisel
0615321ca0 Fix too dark rendering on the Monado runtime
Just like the Windows Mixed Reality runtime, we have to apply a sRGB
OETF to get visually correct-ish looking colors.
We plan to further investigate if it's really WMR and Monado being wrong
here, or if it's Oculus (which doesn't need this additional transform),
but there are some details to check.
2019-10-16 14:36:13 +02:00
Julian Eisel
3bed8a7338 Refactor GPU viewport onscreen drawing for "upside down" drawing
Reduces code duplication for the DirectX specific upside down drawing.
Didn't actually test the upside down drawing, since I need to do that on
Windows.
2019-10-15 22:33:46 +02:00
Julian Eisel
ff03e3b7e0 Merge branch 'master' into soc-2019-openxr 2019-10-15 22:13:16 +02:00
Julian Eisel
350b7b378d Correct/remove disabled code for space conversion
Turns out we don't actually have to convert between spaces.
2019-10-15 22:10:08 +02:00
Julian Eisel
51af7510fb Cleanup: Avoid duplication of projection matrix calculation 2019-10-15 22:09:27 +02:00
Julian Eisel
927c300c02 Improve error messages & cleanup 2019-10-15 22:04:22 +02:00
Julian Eisel
fa9a841d43 Wrap WM XR data into own struct 2019-10-15 17:33:46 +02:00
Julian Eisel
b057298021 Revert accidental change in previour commit
Played around with the color management/transforms but forgot to undo.
2019-10-15 17:12:56 +02:00
Julian Eisel
1ada9f5bf9 Support VR Session settings & add some basic ones
* Adds the needed bits to support VR session settings and access them in
  the VR view drawing code.
* Added settings for: shading mode, grid floor, annotations, clipping.
  More can easily be added.
* The Add-on adds a "VR" tab in the side bar, containing buttons for the
  added settings
2019-10-15 16:01:06 +02:00
Julian Eisel
52c9d33cc2 Merge branch 'master' into soc-2019-openxr 2019-10-14 16:05:46 +02:00
Julian Eisel
db6657aa15 Fix compile error on Windows after last commit 2019-10-11 15:40:03 +02:00
Julian Eisel
941e1f5a98 Strictly follow specification to get OpenXR extension functions
This fixes linking errors with the Monado runtime. The specification
says that extension functions have to be gotten through
`xrGetInstanceProcAddr()` which we did for some extensions, but not for
the graphics extensions. Worked fine earlier, but broke meanwhile.
2019-10-10 14:47:00 +02:00
Julian Eisel
e9832f053b Merge branch 'master' into soc-2019-openxr 2019-10-10 11:30:14 +02:00
Julian Eisel
cddf043cca Cleanup: Don't pass unused lens value 2019-09-17 19:16:14 +02:00
Julian Eisel
6af2f222ca Cleanup: Comment style 2019-09-17 19:02:01 +02:00
Julian Eisel
639dffa43a CMake: Slight adjustment to warning message 2019-09-17 18:17:58 +02:00
Julian Eisel
9baa9e2bd3 Fix Linux linker config name for the OpenXR-SDK 2019-09-17 16:55:24 +02:00
Julian Eisel
3c38e67765 Fix mistakes in openxr build options
I remember merge conflicts here.
2019-09-17 16:54:28 +02:00
Julian Eisel
1849e4fe19 Merge branch 'master' into soc-2019-openxr 2019-09-17 13:48:54 +02:00
2ef7a1f24d Merge branch 'master' into soc-2019-openxr 2019-09-15 19:01:30 +02:00
Julian Eisel
bc8186b5d1 Merge branch 'master' into soc-2019-openxr 2019-08-30 14:22:04 +02:00
Julian Eisel
e0bb3f9286 Merge branch 'master' into soc-2019-openxr 2019-08-24 23:21:33 +02:00
Julian Eisel
d0b4ec00f6 Don't drwa relationship lines in the VR view 2019-08-24 22:06:23 +02:00
Julian Eisel
7b6514c222 Merge branch 'master' into soc-2019-openxr 2019-08-24 14:45:41 +02:00
Julian Eisel
c506acf2fc Add Oculus to the list of known runtimes
With this, all currently available runtimes are in the runtime map. So
removing the TODO comment.
2019-08-24 03:35:32 +02:00
Julian Eisel
31b8350b01 Cleanup: Refactor (hacky) swapchain image submission
Code now assumes that the view-draw callback left the OpenGL state for
ongoing use by Ghost-XR. So the state doesn't have to be set by the
swapchain image submission and thus it we don't need to pass the Ghost
OpenGL context to it in a hacky way.
Also, rename drawViewEnd (to submitToSwapchain) and remove
drawViewBegin.
2019-08-24 03:32:11 +02:00
Julian Eisel
d7a216704b Fix warning in release builds 2019-08-24 03:17:14 +02:00
Julian Eisel
4b67477732 Own FBO for VR viewport to get previous changes to work 2019-08-24 03:15:25 +02:00
Julian Eisel
4a039158e5 Avoid OpenGL context deactivation, just to reactivate it immediately 2019-08-24 00:13:36 +02:00
Julian Eisel
61014e1dd9 Remove hack to resize the usable default framebuffer region 2019-08-23 23:46:09 +02:00
Julian Eisel
3441314e40 Remove blitting from default framebuffer 2019-08-23 23:36:04 +02:00
Julian Eisel
f175dcc35f Add Monado to the list of known runtimes 2019-08-23 23:08:21 +02:00
Julian Eisel
756b676076 Merge branch 'master' into soc-2019-openxr 2019-08-23 17:51:28 +02:00
Julian Eisel
7462fca737 Avoid redundant framebuffer resize and offscreen texture drawing 2019-08-23 17:46:43 +02:00
Julian Eisel
7c9e18c193 Cleanup: Add comments 2019-08-23 17:00:30 +02:00
Julian Eisel
6b69b5349b Address and remove some TODOs marked in code 2019-08-22 23:24:05 +02:00
Julian Eisel
daba8140c2 Cleanup: Unused functions, add comments, sync to master 2019-08-22 23:02:01 +02:00
Julian Eisel
599d0611b0 Improve batch file text for starting Blender with Oculus support 2019-08-22 13:33:06 +02:00
Julian Eisel
e88970db82 Don't create a DirectX swap-chain
We only render offscreen anyway. There's no point in creating a
swap-chain. This simplifies things quite a bit.
2019-08-21 20:58:59 +02:00
Julian Eisel
20b0b36479 DirectX: Create an own render-target, don't use swapchain for blitting 2019-08-21 20:40:13 +02:00
Julian Eisel
2c77f2deac Remove GHOST API functions for OpenGL offscreen blitting
These were previously used to blit from a offscreen (non-OpenGL)
context, into an onscreen one. We do this differently, and only within
GHOST_XrGraphicsBinding now, so this can be removed.
2019-08-21 20:36:40 +02:00
Julian Eisel
fec7ac7c51 Refactor OpenGL/DirectX resource sharing for multiple shared resources
Rather than max. one shared resource per DirectX context, code can now
request a handle for a shared resource and ask the DirectX context to do
operations on that.
2019-08-21 19:44:08 +02:00
Julian Eisel
2a1ec8ec2a Fix missing CMake hint for OpenXR SDK path on linux 2019-08-21 13:24:16 +02:00
1548682cde Windows/deps: Add/fix openxr_sdk dependency
There were a few typos here and there, and the openxr_sdk does not respect the cflags we give it hence a patch was added to work around this undesirable behaviour.
2019-08-20 08:30:29 -06:00
Julian Eisel
588dea6751 Merge branch 'master' into soc-2019-openxr 2019-08-20 12:36:51 +02:00
Julian Eisel
ad4f9a4d98 Fix compiling with WITH_OPENXR disabled 2019-08-20 09:17:56 +02:00
Julian Eisel
84466c7d71 Blacklist VR add-on in Python tests if WITH_OPENXR is disabled 2019-08-20 00:55:21 +02:00
Julian Eisel
de037b031d Expose WITH_OPENXR build option to Python API 2019-08-20 00:12:59 +02:00
Julian Eisel
a21ae28f96 Prepare Toggle VR Session operator to be enabled by an add-on 2019-08-19 23:44:59 +02:00
Julian Eisel
b2424bd781 Windows: Print warning and disable WITH_OPENXR if SDK is not found 2019-08-19 15:41:27 +02:00
Julian Eisel
d0177fc541 Integrate the OpenXR SDK better into dependency management
Adds the SDK so that `make deps` works, on all platforms. On Windows,
the SDK headers and libraries are now assumed to be in the usual lib\
directory.
Also fixes a mistake in install_deps.sh

Note that none of this is tested as it requires an older Visual Studio
version than I have.
2019-08-18 13:06:48 +02:00
Julian Eisel
4cf8740790 Fix compile error on Linux 2019-08-17 23:59:39 +02:00
Julian Eisel
a53b90329a Merge branch 'master' into soc-2019-openxr 2019-08-17 23:58:09 +02:00
Julian Eisel
2c41ffa380 Fix compiling with external OpenXR SDK on Windows 2019-08-15 21:49:10 +02:00
Julian Eisel
cdc2768f65 Cleanup: Don't cast away const in GHOST C-API 2019-08-15 15:52:45 +02:00
Julian Eisel
eb477c67a1 Fix crash when no OpenXR runtime is found (or setup failed) 2019-08-15 15:50:01 +02:00
Julian Eisel
0dd3f3925b Remove bundled OpenXR-SDK sources from extern/
Removes the OPENXR_USE_BUNDLED_SRC option which allowed using the
OpenXR-SDK sources bundled in extern/. It would be too much hassle to
keept these updated.
Now these have to be provided on the system Blender is compiled on. I've
already added necessary bits to install_deps.sh and our Windows
maintainer is ready to provide builds with OpenXR-SDK linked.
Once this gets into master, platform maintainers will have to be
notified about the added dependency.

This also removes the JsonCpp dependency, it was only needed for the
OpenXR-SDK sources.
2019-08-15 15:42:23 +02:00
Julian Eisel
9e7c48575a Linux: Add OpenXR-SDK to install_deps.sh 2019-08-14 22:59:33 +02:00
Julian Eisel
8138099fa9 Silence warnings in OpenXR SDK API layer files 2019-08-14 17:44:02 +02:00
Julian Eisel
02de1b9860 Quiet warning 2019-08-14 16:11:14 +02:00
Julian Eisel
57712625f2 Merge branch 'master' into soc-2019-openxr 2019-08-14 16:01:30 +02:00
Julian Eisel
96a34d7f50 Cleanup: Unused includes, better structuring for wm_xr.c 2019-08-09 16:35:28 +02:00
Julian Eisel
873223f38d Cleanup: Remove unused support for non-OpenGL Windows
This was very useful for testing, but there's no current need for it.
Neither for VR code, nor for anything else in master.
2019-08-09 16:08:34 +02:00
Julian Eisel
716c6b0c01 Cleanup: Move secondary GHOST-context handle to XR surface data
This is used to refer to the DirectX context. For other (currently
non-existant) surfaces, this may not make much sense.
2019-08-09 13:29:08 +02:00
Julian Eisel
62bbd2e37d Don't swap buffers of offscreen surface OpenGL contexts
This does frame syncing to the regular screen, so hurts performance in
some cases.
2019-08-08 22:00:21 +02:00
Julian Eisel
ba223dfac8 Exit OpenXR context/session gracefully if the runtime reports loss pending
Handle XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING and
XR_SESSION_STATE_LOSS_PENDING according to the specification.
2019-08-07 23:58:28 +02:00
Julian Eisel
8557997e81 Disable specular highlights in the VR viewport 2019-08-07 23:05:24 +02:00
Julian Eisel
bcc8f7c6be Fix xrDestroy calls to data already implicitly destroyed by OpenXR
Would effectifely result in null-ops, since the loader does good sanity
checks. The failing functions would still lead to error prints though.
2019-08-07 22:17:55 +02:00
Julian Eisel
fe7b01a08f Correctly request session end according to OpenXR 1.0 specification 2019-08-07 22:13:35 +02:00
Julian Eisel
5350015d51 Fix dark VR rendering on Windows Mixed Reality by appyling SRGB OETF
Discussed this in length with @sobotka, and it seems WMR has an utterly
broken pixel color pipeline. So we apply a SRGB OETF for this specific
runtime to compensate.
2019-08-07 11:52:30 +02:00
Julian Eisel
3483aa57b3 Allow querying OpenXR runtime ID
Useful in case special treatment is needed for certain runtimes.
Currently only WMR gets its ID assigned correctly, others are TODO.
2019-08-07 03:22:33 +02:00
Julian Eisel
44a220f721 Merge branch 'master' into soc-2019-openxr 2019-08-07 02:20:22 +02:00
Julian Eisel
5274c5cce6 Merge branch 'master' into soc-2019-openxr 2019-08-05 12:52:57 +02:00
Julian Eisel
0d70afed19 Merge branch 'master' into soc-2019-openxr 2019-08-02 23:35:40 +02:00
Julian Eisel
03b09dbe32 Fix compile error after merge and warning 2019-08-01 21:53:57 +02:00
Julian Eisel
f04a5ad1e4 Merge branch 'master' into soc-2019-openxr 2019-08-01 21:27:08 +02:00
Julian Eisel
ab1455e972 Fix error in OpenGL version check for OpenXR 1.0 2019-08-01 01:56:35 +02:00
Julian Eisel
b94af38c31 Fix compile error on GCC 2019-08-01 01:39:27 +02:00
Julian Eisel
40db778de3 Add sources for OpenXR core API validation layer
Had to do quite some changes to CMakeLists.txt from the SDK this time.
2019-08-01 00:28:16 +02:00
Julian Eisel
22966f4d35 Address changes in OpenXR 1.0 to get rendering to work again 2019-07-31 02:19:35 +02:00
Julian Eisel
e8f66ff060 Update OpenXR to version 1.0
Only tested on Windows.

Updates loader sources from the OpenXR SDK to latest 1.0 SDK and updates
requiremed version to 1.0. The compile time generation of files is a
thing of the past now (although you can still force it).
1.0 got released yesterday. Only one line needed fixing in our OpenXR
code to get it to compile. Rendering is black though.

For now I tried to keep edits to CMakeList.txt files minimal. So now
there are OpenXR CMake options exposed (with bad names), CMake prints,
etc.
2019-07-31 02:18:28 +02:00
Julian Eisel
9ac33e56a1 Merge branch 'master' into soc-2019-openxr 2019-07-30 22:19:41 +02:00
Julian Eisel
091cc94379 Use fixed lighting, don't make it rotate with view rotation 2019-07-24 16:41:46 +02:00
Julian Eisel
fc31be5ab0 Fix broken VR viewport rotation and movement 2019-07-24 02:52:03 +02:00
Julian Eisel
aff49f607a Use draw manager offscreen context for the VR session
This way we avoid the big overhead of context switches. Makes frames
render about twice as fast here. For heavy Spring scenes I'm getting
around 20 FPS here, classroom scene is at 50 FPS.
This is great given that drawing itself still isn't optimized for dual
eye rendering.
2019-07-24 01:39:04 +02:00
Julian Eisel
57b77cd193 Print 8 Frame average FPS for --debug-xr-time
Much more useful than a per frame FPS estimation. 8 frames are used for
the Blender viewport FPS stats too.
Refactored drawing data storage a bit.
2019-07-23 19:16:39 +02:00
Julian Eisel
d58eb8d29d Add --debug-xr-time command line option for VR frame time info prints
Outputs frame render time in milliseconds and FPS this time would add up
to. We could average times so FPS is a bit more stable, but the
precision of un-averaged results may be helpful too.
2019-07-23 02:06:08 +02:00
Julian Eisel
a4310ba85f Merge branch 'master' into soc-2019-openxr 2019-07-23 00:18:08 +02:00
Julian Eisel
bd42740ef1 Silence GCC warning 2019-07-21 13:15:00 +02:00
Julian Eisel
679a4c34fc Fix compile error with bundled OpenXR sources 2019-07-21 03:18:02 +02:00
Julian Eisel
55362436d9 Fix troubling memory leak in offscreen viewport drawing
I'm not really sure why the leak happened - draw manager kept allocating
certain buffers - but I figured I could avoid it by not recreating
GPU_offscreen/GPU_viewport on every redraw.
This should also improve performance a bit.
2019-07-21 01:10:18 +02:00
Julian Eisel
c1d164070b Pure OpenGL backend works now, let it take priority over DirectX 2019-07-20 19:34:50 +02:00
Julian Eisel
3a4034a741 Make OpenGL-only session backend work
Previously, only DirectX HMD rendering would work (and still takes
priority).
2019-07-20 19:33:11 +02:00
Julian Eisel
a0be113d2e Fix DirectX context not freed on session exit
Also rename XrSurfaceData to wmXrSurfaceData
2019-07-17 15:18:27 +02:00
Julian Eisel
151fb129e7 Fix for previous commit, accidental call to xrDestroySwapchain 2019-07-17 14:51:21 +02:00
Julian Eisel
165c5a5259 Fix possible OpenXR swapchain leak by using new unique_oxr_ptr 2019-07-17 14:05:06 +02:00
Julian Eisel
74fc1db25b Add helper class to RAII manage OpenXR handles
Adds generic unique_oxr_ptr to wrap xrCreate and xrDestroy functions of
OpenXR handles into a unique_ptr like RAII interface.

While for most cases, OpenXR resources can be freed by their owning
object, sometimes errors may occor before final ownership is established.
E.g. swapchain ownership is only transfered to the session object once
its swapchain-images are created - which may fail. With this RAII
wrapper, the swapchain would be freed on error (as this triggers stack
unwinding through an exception), no matter who holds ownership to it
currently.
There are other solutions to this problem, e.g. by establishing final
ownership right after/upon creation, or by explicit freeing in case an
error is spotted; it's too easy to make mistakes here though. Plus, we
may want to experiment with using this API for all OpenXR resources, to
entirely avoid the possibility of them leaking.
2019-07-17 13:35:14 +02:00
Julian Eisel
03ff2a8dd5 Fix compile error with USE_FORCE_WINDOWED_SESSION enabled
At least get it to compile, this is still kinda broken though.
2019-07-17 11:29:34 +02:00
d99d15f48d Add helper batch file for testing on oculus rift. 2019-07-16 16:41:44 -06:00
Julian Eisel
6a998833cd Temporarily let DirectX take priority over OpenGL
OpenGL doesn't work yet. Shouldn't be too difficult to get working, but
I don't have a working OpenXR runtime with OpenGL support to test here.
2019-07-16 21:48:29 +02:00
Julian Eisel
fca4826c7f Merge branch 'master' into soc-2019-openxr 2019-07-16 21:09:30 +02:00
Julian Eisel
b0845fc133 Fix some issues, improve error message
Fixes:
* Destruct surface when destroying session on error. Fixes null pointer
  dereference when trying to draw the surface on next redraw.
* Fix trying to enable same extensions/API-layers multiple times due to
  static array usage not being cleared after error.
* Null pointer dereference with OpenGL drawing
2019-07-13 16:22:26 +02:00
Julian Eisel
70cf8bd9c6 Fix crash on OpenXR error before context is created fully 2019-07-13 01:19:58 +02:00
Julian Eisel
3a2e459f58 Show useful error reports in case of errors.
E.g. with an active OpenXR runtime installed, but no HMD plugged in,
Blender will now show: "Failed to get device information. Is a device
plugged in?".
In case of such errors, the VR-session will be cleanly exited, with
no side effects to the rest of Blender (at least if there are no bugs).

The GHOST_Xr API now allows setting a custom error handling callback
which may cleanly destroy all GHOST_Xr data.
2019-07-12 19:51:38 +02:00
Julian Eisel
330f062099 Safe and informative GHOST_Xr error handling
This wraps all functions that could fail into some proper (although
unfinished) error handling.

These were the requirements for the error handling strategy:
* If an error occurs, cleanly exit the VR session (or the context if the
  error happend during its set up), causing no resource leaks or side
  effects to the rest of Blender.
* Show a *useful* error message to the user.
* Don't impair readability of code too much with error handling.

After some back and forth I decided Ghost internal exceptions are the
best way to go about this. I get exceptions are a controversial feature,
IMHO that's because most people use them 'wrong' however. Here's the
rationale:
* Most alternatives require early exiting functions. This early exiting
  has to be 'bubbled up' the call stack to the point that performs error
  handling. So the code gets really impaired by error checking. Tried
  this first and wasn't happy with it at all. Even if error handling is
  wrapped into macros.
* All GHOST_Xr resources are managed via RAII. So stack unwinding will
  cause them to be released cleanly whenever an exception is thrown.
* GHOST_Xr has a clear boundary (the Ghost C-API) with only a handful of
  public functions. That is the only place we need to have try-catch
  blocks at.
  (Generally, try-catch blocks at kinda random places are a bad code
  smell IMHO. Module boundaries are a valid place to put them.)
* Exceptions allow us to pass multiple bits of error information through
  mulitple layers of the call stack. This information can also be made
  specific with a useful error message.
  As of now, they conain a user error message, the OpenXR error code (if
  any), as well as the exact source code location the error was caught
  at.

So if an error is caught inside GHOST_Xr code, an exception is thrown
with specific and hopefully useful information in it. In the Ghost C-API,
these exceptions are caught and passed on to a custom error handling
callback. This callback will be defined by the Blender window-manager
and output the error information via a usual user report popup (not done
yet). It can also ensure the entire session is shut down.

Note that the majority of errors OpenXR can return are for invalid API
usage. Assuming the API usage is valid though, most error messages
should never reach users and can be left a bit more vague. Maybe we can
add something like "This is probably a bug and should be reported" to
those.
2019-07-12 14:40:50 +02:00
Julian Eisel
09872df1c7 Check runtime DirectX requirements for graphics binding too 2019-07-11 21:05:13 +02:00
Julian Eisel
67d6399da6 Check runtime OpenGL requirements prior to creating graphics binding
DirectX will need these checks too.
Also fix warnings due to wrong printf formatting.
2019-07-11 20:36:54 +02:00
Julian Eisel
c29724912b Merge branch 'master' into soc-2019-openxr 2019-07-11 20:28:19 +02:00
Julian Eisel
99560d9657 Disable debug extension on Windows
Unfortunately, enabling XR_EXT_debug_utils crashes instance creation
with the Windows Mixed Reality runtime. Maybe I'm doing something wrong,
for now, just disable it.
2019-07-11 16:44:51 +02:00
Julian Eisel
b8a7b87873 General minor fixes and cleanup
* Initialize all class member variables
* Add version to runtime name printing
* Separate functionality code from debug prints
* Improve code structure using Doxygen groups
* Make accessors const functions
* Add (Doxygen) comments
* Naming
* Reorder functions
2019-07-11 16:36:04 +02:00
Julian Eisel
c9f6c1a054 Fix wrong return value causing OpenXR initialization to fail 2019-07-11 00:51:00 +02:00
Julian Eisel
dd0fcb50b4 Fix compile errors on windows and with bundled OpenXR SDK sources 2019-07-11 00:50:10 +02:00
Julian Eisel
c1e9cf00ac Refactor GHOST_XrContext into class + interface
Makes GHOST_Xr much more consistent with the rest of GHOST. Basically I
added a GHOST_IXrContext interface which can be called by the GHOST
C-API. The internal GHOST_XrContext class implements this.
Outside of GHOST only the opaque GHOST_XrContextHandle is accessible.

Kept GHOST_Xr_intern.h and GHOST_Xr.cpp for now. I'll probably remove
them soon. There's not much reason for both of them to be there.
2019-07-10 23:53:07 +02:00
Julian Eisel
84d609f67b Use OpenXR extension for extra debug messages in debug mode
Enables (or tries to) the XR_EXT_debug_utils extension which allows
setting a custom callback for additional debug prints. Note that I
haven't been able to test this really, as the Monado runtime appears to
not have this fully implemented (had to force sending a custom message
to find that out...). Will test with the Windows MR runtime in a bit. We
can also improve message quality then (it can print the exact function
name the message was sent from, print additional custom labels which
could indicate session state, etc.).
2019-07-10 15:08:52 +02:00
Julian Eisel
86178548d5 Only try to enable OpenXR API validation layer in debug mode 2019-07-10 15:08:10 +02:00
Julian Eisel
d711540a85 Cleanup: Rename XR_DEBUG_BEGIN -> XR_DEBUG_ONLY_BEGIN
Of course also renames XR_DEBUG_END accordingly.
2019-07-10 15:06:08 +02:00
Julian Eisel
6e3158cb00 Only print info messages with --debug-xr enabled 2019-07-09 17:49:54 +02:00
Julian Eisel
b216690505 Add --debug-xr commandline arg and pass on to GHOST XR contexts
Doesn't do anything yet.
2019-07-09 17:20:01 +02:00
Julian Eisel
b98896ddd9 Preparations to allow enabling OpenXR API validation layer
For this to work two environment variables have to be set:
XR_API_LAYER_PATH and LD_LIBRARY_PATH, both have to point to the API
layers built by the OpenXR SDK. It also requires you compile Blender
linked to your own SDK build (OPENXR_USE_BUNDLED_SRC disabled).
Further changes will make this set up unnecessary, so validation layers
can be enabled via some flag.
2019-07-09 16:45:21 +02:00
Julian Eisel
a05104d61f Fix warnings and compile error on GCC 2019-07-09 11:28:17 +02:00
Julian Eisel
7fe1cc8d24 Enable grid floor in VR session
Helps quite a bit orientating.
2019-07-09 10:56:37 +02:00
Julian Eisel
70e84a2c20 Merge branch 'master' into soc-2019-openxr 2019-07-08 14:18:08 +02:00
Julian Eisel
084a33ca94 Use base pose from Blender camera
I was trying to set the camera pose as OpenXR reference pose. But then I
got really strange poses for drawing back from OpenXR. Couldn't figure
out a way to solve this.
Now we just apply OpenXR's draw pose to the Blender camera pose. If we
later want to support moving around in the scene (e.g. via teleporting),
that has to be changed.

Also uses flipped drawing for DirectX surface to correct DirectX upside
down drawing (compared to OpenGL).
2019-07-08 14:13:14 +02:00
Julian Eisel
37f619aea3 Don't recreate reference local space on each redraw
Set this up on session start.
2019-07-07 13:07:51 +02:00
Julian Eisel
6904ab10f4 Add GHOST_XrSession class for cleaner & safer session management
Session code and data structures are now localized. But also, this
enables sessions to use deterministic destruction to end itself cleanly.
So whenever an error occurs, we can use stack unwinding which will cause
graceful ending of the session.
2019-07-07 12:45:37 +02:00
Julian Eisel
146ef0dd1e Properly end VR sessions fixing crash on next session start
Previously, you had to restart Blender to start another session.
2019-07-03 21:01:58 +02:00
Julian Eisel
5891e86420 Cleanup GHOST_Xr types and functions
* Move GHOST_Xr types to GHOST_Types.h
* Add GHOST_XrPose. We'll have to pass around pose data at multiple
  places.
* Don't require extra call to prepare session rendering, handle
everything through GHOST_XrSessionStart
* Naming
2019-07-01 19:04:54 +02:00
Julian Eisel
2cedad990a Initial HMD viewport rendering (DirectX only first)
Finally: This makes it possible to render a viewport to an HMD via
OpenXR. Pure OpenGL rendering will need some more tweaks to work.
To my great delight, performance is quite good for reasonably sized
scenes.

Had to do some hacks and marked some TODOs. Nothing too bad though.

Here are a couple of notes:
* Current initial pose is pretty useless, think it just looks downwards
  from world origin. Will change that soon.
* The rendered viewport has some issues: Too dark (bad lighting?), grid
  doesn't show up even though I told it to, lighting seems to change with
  view position/rotation, etc. Needs some polish.
* Ideally we'd just use the D3D11 Texture given to us via the OpenXR
  swapchain and blit the OpenGL framebuffer into that. However the
  NV_DX_interop extension fails doing this. Seems like this is a NVidia
  Optimus only issue, but I'm missing the hardware to confirm.
  So instead, we blit into the D3D11 back buffer first and then into the
  Texture.
* The draw-manager uses its own offscreen context so we have to get the
  render result from the draw-manager context to the VR session's
  context first. Luckily I've already added code to support blitting from
  one OpenGL context into another. But it requires blitting twice.
  Blitting should be very cheap, but still...
  Draw-manager could get a context to use passed instead.
2019-07-01 15:57:32 +02:00
Julian Eisel
109be29e42 Draw offscreen viewport in XR session surface callback
Not visible yet, but it should draw in the offscreen. The way this is
now, we don't depend on the Window->Workspace->bScreen->... chain. We
simply draw an offscreen viewport in the draw callback of the XR session
surface.

The drawing also uses view and projection matrices from OpenXR (or
calculated from OpenXR data).
2019-06-29 02:30:23 +02:00
Julian Eisel
13442da69f Move WM level XR functions to wm_xr.c
Operator is still in wm_operators.c, but only calls wm_xr.c functions.
2019-06-28 22:53:46 +02:00
Julian Eisel
231dbd53bf Support Window-less (offscreen) VR session on Windows
Uses the new wmSurface type (non-window drawable container) to manage
the OpenGL, DirectX and GPU module contexts. The draw callback of the XR
surface calls the GHOST_Xr session drawing routines.

What you should see when starting a VR session now (using the WMR
runtime): The Windows Mixed Reality Portal pops up, and a blue
background is drawn on the HMD. This is from the blue color clear call
we do in the drawing preparations of the GHOST_Xr session drawing.
2019-06-28 16:24:24 +02:00
Julian Eisel
d3e48fb096 Merge branch 'master' into soc-2019-openxr 2019-06-28 14:09:08 +02:00
Julian Eisel
d544a0b41c Avoid std::vector copy 2019-06-28 13:56:10 +02:00
Julian Eisel
cf4799e299 Add wmSurface for non-Window offscreen VR session drawing
Adds a wmSurface type which acts as a container for non-Window (offscreen)
draw surfaces. Ideally wmWindow would of course also just do C-style
inheritance from wmSurface, but I guess they can co-exist too.
For the VR session a surface is created on Linux and passed to the
graphics binding to use.

Note this is not used on Windows yet, it still opens a window there.
2019-06-28 13:38:34 +02:00
Julian Eisel
57d9f004aa Fix compile/CMake errors and warnings on Linux 2019-06-27 19:55:22 +02:00
Julian Eisel
62cde7a9ef Finish VR view drawing callback set up
* Allow passing custom data to session draw function, passed to the
  callback
* Actually call the callback
* Create and bind a WM level callback. Will later be used to draw the
  viewport.

Also, check if session is actually visible before drawing.
2019-06-27 19:17:12 +02:00
Julian Eisel
e4fcf25fc5 Don't use Microsoft::WRL::ComPtr<...> for COM types
Makes things difficult if you're not familar with COM.
2019-06-27 18:56:20 +02:00
Julian Eisel
215c919b33 Merge branch 'master' into soc-2019-openxr 2019-06-26 18:39:31 +02:00
Julian Eisel
da44a02d00 The first pixels pushed to Windows Mixed Reality HMDs!
Just a clear call for now, so all you see is a blue world. This blue
"world" is however drawn by Blender!

Also fixes use after destruction of compositor layer data.
2019-06-24 21:22:23 +02:00
Julian Eisel
867007d9d7 Set up OpenXR compositing layers for drawing
That should be one of the last steps to prepare pushing pixels to HMDs.
Fingers crossed!
2019-06-24 16:44:43 +02:00
Julian Eisel
e9ea814233 Merge branch 'master' into soc-2019-openxr 2019-06-24 12:52:37 +02:00
Julian Eisel
6b43c82cb5 Set up OpenXR views and spaces for drawing
Using a dummy identity pose at {0, 0, 0} to start with. This should
later use the current viewport position & orientation I guess.

Also adds function to set a draw callback. There's quite some OpenXR
related stuff to be done before and after drawing anyting, as well as
before and after drawing each view (eye). Quite some info would have to
be exposed to WM to let it manage drawing. So I think using a callback
called from GHOST_Xr to draw each eye instead is a good way to go.

VR session currently crashes after opening. Seems to be related to
blocking frame wait call. I'm not too worried about that though, might
disappear once OpenXR frame sync functions get proper timing info
passed.
2019-06-23 18:27:24 +02:00
Julian Eisel
afbb62fecd Bring back wm_xr.c for higher level XR functions 2019-06-23 15:42:18 +02:00
Julian Eisel
8a676e8fa9 Execute necessary OpenXR frame timing calls 2019-06-23 13:47:42 +02:00
Julian Eisel
c52111e983 Correctly destruct swapchain on shutdown 2019-06-23 02:46:25 +02:00
Julian Eisel
d749e8a2c4 Create graphics binding specific swapchain images
Following the OpenXR SDK's example code very closely here. We have to do
some nasty converting of graphics binding specific image vectors to
generalized base ones. The SDK's approach seems like a good way to go
about this.
2019-06-23 02:12:38 +02:00
Julian Eisel
8663aa80e6 Use abstract class/interface for generalized graphics binding operations
Rather than having switch case blocks throughout the session code, give
binding operations an own interface with dedicated implementations.
2019-06-23 00:37:17 +02:00
Julian Eisel
88b39444a0 Fix error causing sessions to not start correctly
With this, the Windows Mixed Reality Portal finally pops up when
starting the session. That is how it's supposed to work. After it's
initialization phase all you see is black. That's expected too as we
don't send anything to the device yet.
2019-06-22 22:08:50 +02:00
Julian Eisel
4cfc3caa09 OpenXR swapchain creation
Nothing special to say. Just calls needed OpenXR functions to create
swapchains. Swapchain images are not created yet.

Interestingly, the Windows Mixed Realtiy portal now pops up when closing
Blender after having created a VR session. So we're getting closer ;)
2019-06-22 21:25:58 +02:00
Julian Eisel
28428b3462 Merge branch 'master' into soc-2019-openxr 2019-06-21 22:31:01 +02:00
Julian Eisel
24146563a0 Cleanup: Use CamelCase for XR functions/types
Also silence warnings.
2019-06-21 22:27:40 +02:00
Julian Eisel
2ee9c60c20 Finish OpenXR GLX binding initialization
Monado now opens a window here when asking it to start a session. That
seems to be the case because it doesn't detect the HMD as direct mode
capable yet. But that shouldn't be an issue from our side.
2019-06-19 21:11:21 +02:00
Julian Eisel
fb64675209 Fix invalid delete operator use
Again a thing MSVC should warn about but didn't...
2019-06-19 19:09:40 +02:00
Julian Eisel
76385139cf Use friend class to access graphics data on Windows too
Also fix memory leak.
2019-06-19 18:30:19 +02:00
Julian Eisel
b18f5a6a81 Pass graphics context data to OpenXR graphics bindings on Linux too
Refactors function into a class, and make this class a friend of
GHOST_ContextGLX. That seems like a better way to access low level
graphics data for this specific case, rather than giving anyone access
via a getter.
2019-06-19 17:23:41 +02:00
Julian Eisel
9d29373b06 Init OpenXR graphics bindings with valid graphics context (Win only)
Will do this for Linux in a separate commit.

Also fixes a stupid mistake from previous commit on lazy-creation of XR
context.
2019-06-19 12:20:18 +02:00
Julian Eisel
f2f1e4dfed Remove CTX_wm_xr_context
Not really useful, plus XR-Context is now GHOST data.
2019-06-19 01:00:37 +02:00
Julian Eisel
0da0f29ade Rename of XR types (WM -> GHOST) 2019-06-19 00:57:50 +02:00
Julian Eisel
a8519dbac2 Lazy-create XR-context
Creating the context causes the OpenXR loader to try connect to a
runtime. That would involve reading the OS'es active_runtime.json and
dynamic linking based on that. So better avoid doing this on startup.
Also: don't pay for what you don't use!
2019-06-19 00:44:42 +02:00
Julian Eisel
d15d07c4f6 Rename wm_xr_ -> GHOST_XR 2019-06-19 00:28:37 +02:00
Julian Eisel
d356787a65 Merge branch 'soc-2019-openxr' into temp-ghost_openxr 2019-06-18 23:50:28 +02:00
Julian Eisel
a284fa3abb Merge branch 'master' into soc-2019-openxr 2019-06-18 23:49:54 +02:00
Julian Eisel
4eeb7523e9 Use some C++ features where useful
Also correct include guards.
2019-06-18 01:02:33 +02:00
Julian Eisel
f30fcd6c85 Initially move XR files to GHOST and compile in C++ 2019-06-17 23:45:28 +02:00
Julian Eisel
47e8133520 Merge branch 'master' into soc-2019-openxr 2019-06-17 22:24:51 +02:00
Julian Eisel
3fa7d59a04 Fail without crashing if no runtime is found
For now simply do nothing. Plan is to work on proper error handling and
reporting later.
2019-06-17 01:24:07 +02:00
Julian Eisel
df8dc43946 Fix compile errors and warnings on certain configs
Addresses:
* Compile error on Linux
* Compile error with WITH_OPENXR disabled
* Unused parameter warnings
2019-06-16 23:28:14 +02:00
Julian Eisel
3b0a2fecfc Fix missing return value... how did this work even?
Looking at the code this should've failed miserably. No idea how this
could still work fine... Maybe return vars used same stack location?
2019-06-16 23:12:13 +02:00
Julian Eisel
80af6d534d Merge branch 'master' into soc-2019-openxr 2019-06-16 22:58:56 +02:00
Julian Eisel
71c7d61808 Draw OpenGL framebuffer upside down in DirectX windows
DirectX is Y coordinates top to bottom, while OpenGL is the opposite.
For the final window manager on-screen drawing, draw to a texture first
and draw that upside down if needed.
2019-06-16 21:46:57 +02:00
Julian Eisel
637b803b97 Support drawing the VR view into a DirectX window!
Phew! That a fight. But this is also a pretty important feature as it
allows interfacing with Windows Mixed Reality OpenXR runtime and the
HMDs supported by it.

Important remaining issue: The rendered viewport is upside down :) That
is of course because DirectX has the opposite vertical direction than
OpenGL.

When creating a DirectX window, we also create an OpenGL offscreen
context to use for all drawing. Just before swapping framebuffers, the
DirectX window blits the framebuffer of the offscreen context into its
swapchain. This requires the WGL_NV_DX_interop and WGL_NV_DX_interop2
extensions.

For testing/dev purposes, also adds:
* Version of the offscreen to onscreen blitting that's OpenGL only. So
  it blits the default framebuffer of the offscreen context into the one
  of the onscreen context.
  This is disabled by a #define.
* Code to draw a colored triangle using DirectX, also for testing.
  Requires the D3DCompiler.lib to be available at compile time. This is
  also disabled using a #define.
2019-06-16 21:05:21 +02:00
Julian Eisel
314eef0df8 Merge branch 'master' into soc-2019-openxr 2019-06-14 20:41:09 +02:00
Julian Eisel
34fa0f8ac6 Set up DirectX window to support drawing
With this the VR window should open fine and get cleared in a red-ish
orange using Direct3D 11 calls (well, on Windows that is).

The window still draws a 3D view to an offscreen buffer. Where we
usually just swap the buffers, we now allow calling a GHOST function to
blit the offscreen OpenGL buffer to whatever type of graphics buffer the
window uses (DirectX here).
The nice thing about this approach is that all DirectX code stays in
GHOST_ContextD3D.cpp. And the entire compatibiliy code can go into a
single function higher level modules don't need to care about.

This also fixes a number of issues introduced in earlier commits.
2019-06-14 19:07:10 +02:00
Julian Eisel
16366724bd Draw into OpenGL offscreen context in the DirectX window.
The window doesn't show anything of course. However we draw (at least I
assume it does) as regular, just into a window offscreen context.

A valid 3D view is created in the window. It's not visible but you see
cursor changes as you move over the window. So handling works.
2019-06-14 02:41:59 +02:00
Julian Eisel
fc8127d070 (Disabled) code to open a DirectX window with the VR session
The window immediately crashes, hence keeping it disabled for now.

Not sure how much of this I'll leave in, for now this is mainly for
testing DirectX compatibility.
2019-06-13 23:24:30 +02:00
Julian Eisel
3ac37fb552 Fix compile errors with older MSVC/Win-SDK versions
Reported by @LazyDodo, thanks!
2019-06-13 18:22:26 +02:00
Julian Eisel
8e51a75772 Fix mistake causing compiler error on Windows
Stupid one...
2019-06-12 23:45:19 +02:00
Julian Eisel
ba2dab402d Merge branch 'master' into soc-2019-openxr 2019-06-12 21:28:40 +02:00
Julian Eisel
796994d222 Refactor graphics context binding to avoid memory leaks
* Retrieve graphics context to bind through callbacks so the XR code can
  manage their lifetime.
* Use static union to store system & chosen graphics lib specific
  graphics binding data.

Makes some things a bit cleaner, too.
2019-06-12 21:27:00 +02:00
Julian Eisel
66e90e9179 Fix compile error and warning on GCC 2019-06-12 19:28:51 +02:00
Julian Eisel
1404edbe3a Support DirectX Ghost context creation
Adds support for creating a DirectX 11 Ghost context. It's not used yet
and more stuff besides creation is needed. Also, other versions than 11
should probably be supported.
We need a DirectX context to support the Windows Mixed Reality OpenXR
Runtime, a rather important one to support. Idea is to use an extension
for OpenGL-DirectX interoperability for drawing the OpenGL offscreen
viewport render using DirectX.
2019-06-12 11:34:21 +02:00
Julian Eisel
2f68a76409 Split wm_xr.c into multiple files
Similar to gizmo/ and message_bus/, there's now a xr/ directory
containing header files and a intern/ directory for source and internal
header files.

Guess this is reasonable to do. And better to do early on to avoid
loosing much git history.
2019-06-11 17:52:04 +02:00
Julian Eisel
304d9a20fc Fix compile errors and crashes on Windows
* Include needed Windows/DirectX headers
* Disable zero sized arraz (GCC extension)
* Add missing break causing failling assert
* Add missing semicolon in Win only code :)
2019-06-11 16:35:31 +02:00
Julian Eisel
b169e327bf Fix compile error with system OpenXR SDK
Graphics binding types were disabled by a compiler flag then.
2019-06-11 14:18:35 +02:00
Julian Eisel
7238bbecc4 Cleanup: Rename graphics-lib to graphics-binding 2019-06-10 22:16:09 +02:00
Julian Eisel
a49b4ca402 Merge branch 'master' into soc-2019-openxr 2019-06-10 22:06:42 +02:00
Julian Eisel
eb0424c946 Proper management of OpenXR graphics bindings for session setup
OpenXR needs to interface with some graphics library (OpenGL, Vulkan,
DirectX, etc.). This is done through graphics binding extensions. The
OpenXR specification requires these to be properly set up before a
session is created.

Adds the following:
* Support priority list of multiple graphics binding extensions (e.g.
  check OpenGL extension availability first, DirectX on Windows second,
  etc.)
* Barebones for passing graphics library data to OpenXR session
  creation. This is highly system dependent, e.g. it requires GLX data
  for OpenGL on X11 systems (XrGraphicsBindingOpenGLXlibKHR). More work,
  including additions to GHOST, will be needed once I get to the more
  graphics related stuff.
* Create an own graphics context for the VR session. It's not doing
  anything useful yet. This is just to fool the Monado OpenXR runtime
  so that it actually attempts to create the OpenXR session.
* Had to add two CMake modules for platform dependent #define's required
  by the OpenXR specification.
2019-06-10 21:59:26 +02:00
Julian Eisel
5d6da57aa3 Cleanup: Move OpenXRData struct out of wmXRContext
Just to make access a bit more convenient.
2019-06-06 18:38:06 +02:00
Julian Eisel
e968bbc5d8 Fix wrong enum-type used for switch
Why doesn't MSVC warn about this, grr...
2019-06-06 17:37:18 +02:00
Julian Eisel
b1b0e05c54 Fix CMake errors after merge (?)
Not sure if this is caused by changes just merged in, or by a system
upgrade I just did. Either way, fixed it now.
2019-06-06 11:25:53 +02:00
Julian Eisel
e547026dfe Merge branch 'master' into soc-2019-openxr 2019-06-06 10:56:19 +02:00
Julian Eisel
f816380af5 Silence warning, fix mem-leak, don't destroy NULL session 2019-06-05 18:03:59 +02:00
Julian Eisel
5e642bfea1 Initial session state handling
To correctly start a session, a graphics extension specific object needs
to be passed to the OpenXR runtime. E.g. for the Windows Mixed Reality
runtime, XrGraphicsBindingD3D11KHR needs to be passed with a valid
DirectX device. Since we don't have any DirectX compatibility working,
I can't test this on Windows yet.
So to test this I finally need to get Monado to work on Linux and
correctly setup the OpenGL extension there.
2019-06-05 16:55:51 +02:00
Julian Eisel
0d1a22f74f Barebones for managing session changes
Adds initial OpenXR event querying so that session state change events
can be handled. Doesn't do any handling yet.
2019-06-05 10:20:51 +02:00
Julian Eisel
20a1af936d Enable graphics extensions if available
Check if available extensions includes the GL one, or the DirectX one on
Windows. Enable them if available.
2019-06-05 01:00:13 +02:00
Julian Eisel
c9c1b90532 Cleanup: Correct local variable name 2019-06-04 18:30:07 +02:00
Julian Eisel
4192281e14 Fix layer and extension count not stored as intended 2019-06-04 18:27:44 +02:00
Julian Eisel
329deadc9e Print OpenXR runtime name once connected 2019-06-04 17:39:12 +02:00
Julian Eisel
53845c554d Merge branch 'master' into soc-2019-openxr 2019-06-04 17:00:58 +02:00
Julian Eisel
35c9e3beed Initial VR-session starting/ending
Adds operator to toggle a VR session, exposed in the Window top-bar
menu. It triggers the needed calls for session creation and destruction.
Setting up the XR-system (a configuration of related devices) is also
done now.

Calling WMR runtime functions fails currently. Not sure why. So while
this executes required routines, it doesn't really work.
2019-06-04 16:42:42 +02:00
Julian Eisel
60f66768cf Fix GCC compile error, warnings and uninitialized use
extension_count could be used uninitialized if no valid OpenXR runtime
was run.
2019-06-02 22:04:52 +02:00
Julian Eisel
3e88974a80 Merge branch 'master' into soc-2019-openxr 2019-06-02 15:24:33 +02:00
Julian Eisel
09e7d6cd26 Correct previous commit
Intended to print out name, not address.
2019-06-02 02:24:04 +02:00
Julian Eisel
5d5ad5d6dd Gather available OpenXR extensions and API-layers on OpenXR setup
We don't actually enable any extension or layer yet. We just put their
names into arrays and print them. The printing can be disabled via a
compiler define, later we should put them behind a proper
logging/debugging mechanism (CLOG).

Also fixes a Visual Studio compile error.
2019-06-01 17:16:49 +02:00
Julian Eisel
e70894c360 Fix compiling with bundled OpenXR SDK sources
Also remove unused include.
2019-05-30 16:22:05 +02:00
Julian Eisel
4c11886c4e Corrections to previous commit
* Remove testing instance creation
* Rename function
2019-05-30 14:56:23 +02:00
Julian Eisel
41e2f2e75f Proper creation & destruction of OpenXR instances
Adds wm_xr.c for an XR management API and creates/destroys the OpenXR
instance through this. This is as planned in my proposal, to lock the
OpenXR calls behind an abstraction.
XR data will be stored in a (non-public) wmXRContext struct within the
window-manager.

For now, creates the OpenXR instance on startup. I think it's better to
lazy setup this, as in, only creating the instance once the user starts
the first XR session. Just to avoid costs for something that may not be
used (the OpenXR loader we use will try loading and parsing the system's
OpenXR active_runtime.json on instance creation). That's for later when
I introduce session management though.

Also added a context getter for the xr-context, which is unused but may
be handy later.
2019-05-30 14:48:13 +02:00
Julian Eisel
864abbd425 Support system installed OpenXR SDK
Adds OPENXR_USE_BUNDLED_SRC so that if disabled, CMake tries to find
the SDK headers and libraries in system paths or in specified root
directory.

I guess this is the way we'd want to do this in master. However for
people testing the branch the bundled sources are much more convenient
(should work out of the box, no need to compile the SDK manually).
2019-05-30 01:44:13 +02:00
Julian Eisel
f333e7eb56 Merge branch 'master' into soc-2019-openxr 2019-05-29 20:14:11 +02:00
Julian Eisel
a2ac2ec3c3 Merge branch 'master' into soc-2019-openxr 2019-05-29 15:17:41 +02:00
Julian Eisel
06d52afcda Linux: OpenXR Linking via OpenXR Loader
Calling OpenXR functions should now work on both Windows and Linux.

Also includes:
* Silence Linux only warnings
* Remove common_cmake_config.h and let CMake generate it when
  configuring (contents vary on system it's compiled on)
* Remove JsonCpp CMake install target
* Remove unnecessary CMakeLists for JsonCpp includes
* Remove unnecessary CMake commands
* Style cleanup
2019-05-28 21:58:18 +02:00
Julian Eisel
e65ba62c37 Windows: OpenXR Linking via OpenXR Loader
Adds needed headers for OpenXR, the loader from the OpenXR SDK and
JsonCpp into extern. Took a while to get this to compile/link, but on
Win10 it works fine now without patching #includes. Linux probably
needs more work.

Added a compile option WITH_OPENXR to toggle XR feature compiling.

Also does a dummy xrCreateInstance() call to test linking.
2019-05-28 01:21:25 +02:00
2520 changed files with 33933 additions and 86303 deletions

View File

@@ -132,7 +132,9 @@ PenaltyBreakAssignment: 100
AllowShortFunctionsOnASingleLine: None
SortIncludes: true
# Disable for now since it complicates initial migration tests,
# TODO: look into enabling this in the future.
SortIncludes: false
# Don't right align escaped newlines to the right because we have a wide default
AlignEscapedNewlines: DontAlign
@@ -191,7 +193,6 @@ ForEachMacros:
- FOREACH_MAIN_ID_BEGIN
- FOREACH_MAIN_LISTBASE_BEGIN
- FOREACH_MAIN_LISTBASE_ID_BEGIN
- FOREACH_MESH_BUFFER_CACHE
- FOREACH_NODETREE_BEGIN
- FOREACH_OBJECT_BEGIN
- FOREACH_OBJECT_FLAG_BEGIN
@@ -214,7 +215,6 @@ ForEachMacros:
- GHASH_ITER_INDEX
- GPU_SELECT_LOAD_IF_PICKSEL_LIST
- GP_EDITABLE_STROKES_BEGIN
- GP_EVALUATED_STROKES_BEGIN
- GSET_FOREACH_BEGIN
- GSET_ITER
- GSET_ITER_INDEX
@@ -238,6 +238,7 @@ ForEachMacros:
- LISTBASE_FOREACH_BACKWARD
- LISTBASE_FOREACH_MUTABLE
- LISTBASE_FOREACH_BACKWARD_MUTABLE
- MAN2D_ITER_AXES_BEGIN
- MAN_ITER_AXES_BEGIN
- NODE_INSTANCE_HASH_ITER
- NODE_SOCKET_TYPES_BEGIN
@@ -245,16 +246,12 @@ ForEachMacros:
- NODE_TYPES_BEGIN
- PIXEL_LOOPER_BEGIN
- PIXEL_LOOPER_BEGIN_CHANNELS
- RENDER_PASS_ITER_BEGIN
- RNA_BEGIN
- RNA_PROP_BEGIN
- RNA_STRUCT_BEGIN
- RNA_STRUCT_BEGIN_SKIP_RNA_TYPE
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN
- SEQP_BEGIN
- SEQ_BEGIN
- SURFACE_QUAD_ITER_BEGIN
- foreach
# Use once we bump the minimum version to version 8.

View File

@@ -186,7 +186,8 @@ if(APPLE)
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" OFF)
mark_as_advanced(WITH_XR_OPENXR)
else()
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" ON)
# Disabled until there's more than just the build system stuff. Should be enabled soon.
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" OFF)
endif()
# Compositor
@@ -319,10 +320,6 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# New object types
option(WITH_NEW_OBJECT_TYPES "Enable new hair and pointcloud objects (use for development only, don't save in files)" OFF)
mark_as_advanced(WITH_NEW_OBJECT_TYPES)
# Misc
if(WIN32)
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
@@ -633,10 +630,9 @@ set_and_warn_dependency(WITH_BOOST WITH_OPENVDB OFF)
set_and_warn_dependency(WITH_BOOST WITH_OPENCOLORIO OFF)
set_and_warn_dependency(WITH_BOOST WITH_QUADRIFLOW OFF)
set_and_warn_dependency(WITH_BOOST WITH_USD OFF)
set_and_warn_dependency(WITH_BOOST WITH_ALEMBIC OFF)
if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD OR WITH_ALEMBIC))
WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD))
message(STATUS "No dependencies need 'WITH_BOOST' forcing WITH_BOOST=OFF")
set(WITH_BOOST OFF)
endif()
@@ -685,7 +681,6 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
set(WITH_X11_ALPHA OFF)
set(WITH_GHOST_XDND OFF)
set(WITH_INPUT_IME OFF)
set(WITH_XR_OPENXR OFF)
endif()
if(WITH_CPU_SSE)

View File

@@ -146,8 +146,8 @@ set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTH
set(PYTHON_HASH d33e4aae66097051c2eca45ee3604803)
set(TBB_VERSION 2019_U9)
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
set(TBB_HASH 26263622e9187212ec240dcf01b66207)
set(TBB_URI https://github.com/01org/tbb/archive/${TBB_VERSION}.tar.gz)
set(TBB_HASH 584edbec127c508f2cd5b6e79ad200fc)
set(OPENVDB_VERSION 7.0.0)
set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)

View File

@@ -29,7 +29,6 @@ if(UNIX AND NOT APPLE)
-DBUILD_WITH_WAYLAND_HEADERS=OFF
-DBUILD_WITH_XCB_HEADERS=OFF
-DBUILD_WITH_XLIB_HEADERS=ON
-DBUILD_WITH_SYSTEM_JSONCPP=OFF
-DCMAKE_CXX_FLAGS=-DDISABLE_STD_FILESYSTEM=1
)
endif()

View File

@@ -63,8 +63,8 @@ build-ffmpeg,build-opencollada,build-alembic,build-embree,build-oidn,build-usd,\
build-xr-openxr,\
skip-python,skip-numpy,skip-boost,\
skip-ocio,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-osd,skip-openvdb,\
skip-ffmpeg,skip-opencollada,skip-alembic,skip-embree,skip-oidn,skip-usd,\
skip-xr-openxr \
skip-ffmpeg,skip-opencollada,skip-alembic,skip-embree,skip-oidn,skip-usd, \
skip-xr-openxr\
-- "$@" \
)
@@ -1289,7 +1289,7 @@ compile_Python() {
./configure --prefix=$_inst --libdir=$_inst/lib --enable-ipv6 \
--enable-loadable-sqlite-extensions --with-dbmliborder=bdb \
--with-computed-gotos --with-pymalloc --enable-shared
--with-computed-gotos --with-pymalloc
make -j$THREADS && make install
make clean
@@ -1310,8 +1310,6 @@ compile_Python() {
INFO "Own Python-$PYTHON_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-python option."
fi
run_ldconfig "python-$PYTHON_VERSION_MIN"
}
# ----------------------------------------------------------------------------
@@ -3130,7 +3128,7 @@ compile_XR_OpenXR_SDK() {
fi
# To be changed each time we make edits that would modify the compiled result!
xr_openxr_magic=2
xr_openxr_magic=0
_init_xr_openxr_sdk
# Clean install if needed!
@@ -3187,9 +3185,8 @@ compile_XR_OpenXR_SDK() {
cmake_d="$cmake_d -D BUILD_WITH_WAYLAND_HEADERS=OFF"
cmake_d="$cmake_d -D BUILD_WITH_XCB_HEADERS=OFF"
cmake_d="$cmake_d -D BUILD_WITH_XLIB_HEADERS=ON"
cmake_d="$cmake_d -D BUILD_WITH_SYSTEM_JSONCPP=OFF"
cmake $cmake_d "-DCMAKE_CXX_FLAGS=-DDISABLE_STD_FILESYSTEM=1" ..
cmake $cmake_d ..
make -j$THREADS && make install
make clean
@@ -5191,7 +5188,7 @@ print_info() {
PRINT ""
PRINT "If you're using CMake add this to your configuration flags:"
_buildargs="-U *SNDFILE* -U PYTHON* -U *BOOST* -U *Boost*"
_buildargs="-U *SNDFILE* -U *PYTHON* -U *BOOST* -U *Boost*"
_buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CYCLES*"
_buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC* -U *USD*"

View File

@@ -7,6 +7,9 @@ message(STATUS "Building in CentOS 7 64bit environment")
set(LIBDIR_NAME "linux_centos7_x86_64")
set(WITH_CXX11_ABI OFF CACHE BOOL "" FORCE)
# Default to only build Blender
set(WITH_BLENDER ON CACHE BOOL "" FORCE)
# ######## Linux-specific build options ########
# Options which are specific to Linux-only platforms
@@ -17,6 +20,12 @@ set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE)
set(WITH_JACK_DYNLOAD ON CACHE BOOL "" FORCE)
set(WITH_SDL_DYNLOAD ON CACHE BOOL "" FORCE)
set(WITH_SYSTEM_GLEW OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP_STATIC ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL_NUMPY ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL_REQUESTS ON CACHE BOOL "" FORCE)
# ######## Release environment specific settings ########
@@ -24,5 +33,13 @@ set(LIBDIR "${CMAKE_CURRENT_LIST_DIR}/../../../../lib/${LIBDIR_NAME}" CACHE STRI
# Platform specific configuration, to ensure static linking against everything.
set(Boost_USE_STATIC_LIBS ON CACHE BOOL "" FORCE)
# We need to link OpenCOLLADA against PCRE library. Even though it is not installed
# on /usr, we do not really care -- all we care is PCRE_FOUND be TRUE and its
# library pointing to a valid one.
set(PCRE_INCLUDE_DIR "/usr/include" CACHE STRING "" FORCE)
set(PCRE_LIBRARY "${LIBDIR}/opencollada/lib/libpcre.a" CACHE STRING "" FORCE)
# Additional linking libraries
set(CMAKE_EXE_LINKER_FLAGS "-lrt -static-libstdc++ -no-pie" CACHE STRING "" FORCE)

View File

@@ -49,7 +49,6 @@ if(NOT LLVM_ROOT_DIR)
OUTPUT_VARIABLE LLVM_ROOT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LLVM_ROOT_DIR ${LLVM_ROOT_DIR} CACHE PATH "Path to the LLVM installation")
set(LLVM_INCLUDE_DIRS ${LLVM_ROOT_DIR}/include CACHE PATH "Path to the LLVM include directory")
endif()
if(NOT LLVM_LIBPATH)
execute_process(COMMAND ${LLVM_CONFIG} --libdir

View File

@@ -95,7 +95,7 @@ FIND_LIBRARY(OPENIMAGEDENOISE_LIBRARY
# handle the QUIETLY and REQUIRED arguments and set OPENIMAGEDENOISE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenImageDenoise DEFAULT_MSG
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENIMAGEDENOISE DEFAULT_MSG
OPENIMAGEDENOISE_LIBRARY OPENIMAGEDENOISE_INCLUDE_DIR)
IF(OPENIMAGEDENOISE_FOUND)

View File

@@ -222,10 +222,12 @@ if(WITH_OPENCOLLADA)
-lMathMLSolver
-lGeneratedSaxParser
-lbuffer -lftoa -lUTF
${OPENCOLLADA_LIBPATH}/libxml2.a
)
# PCRE and XML2 are bundled with OpenCollada.
# PCRE is bundled with openCollada
# set(PCRE ${LIBDIR}/pcre)
# set(PCRE_LIBPATH ${PCRE}/lib)
set(PCRE_LIBRARIES pcre)
set(XML2_LIBRARIES xml2)
endif()
if(WITH_SDL)
@@ -447,9 +449,7 @@ if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5)
# Xcode 5 is always using CLANG, which has too low template depth of 128 for libmv
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
endif()
# Avoid conflicts with Luxrender, and other plug-ins that may use the same
# libraries as Blender with a different version or build options.
# Get rid of eventually clashes, we export some symbols explicitly as local
set(PLATFORM_LINKFLAGS
"${PLATFORM_LINKFLAGS} -Xlinker -unexported_symbols_list -Xlinker '${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map'"
)

View File

@@ -20,6 +20,10 @@
# Xcode and system configuration for Apple.
# require newer cmake on osx because of version handling,
# older cmake cannot handle 2 digit subversion!
cmake_minimum_required(VERSION 3.0.0)
if(NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING
"Choose the architecture you want to build Blender for: i386, x86_64 or ppc"
@@ -41,98 +45,54 @@ execute_process(
OUTPUT_VARIABLE XCODE_CHECK OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "/Contents/Developer" "" XCODE_BUNDLE ${XCODE_CHECK}) # truncate to bundlepath in any case
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
# Unix makefile generator does not fill XCODE_VERSION var, so we get it with a command.
# Note that `xcodebuild -version` gives output in two lines: first line will include
# Xcode version, second one will include build number. We are only interested in the
# former one. Here is an example of the output:
# Xcode 11.4
# Build version 11E146
# The expected XCODE_VERSION in this case is 11.4.
if(${CMAKE_GENERATOR} MATCHES "Xcode")
# earlier xcode has no bundled developer dir, no sense in getting xcode path from
if(${XCODE_VERSION} VERSION_GREATER 4.2)
# reduce to XCode name without dp extension
string(SUBSTRING "${XCODE_CHECK}" 14 6 DP_NAME)
if(${DP_NAME} MATCHES Xcode5)
set(XCODE_VERSION 5)
endif()
endif()
##### cmake incompatibility with xcode 4.3 and higher #####
if(${XCODE_VERSION} MATCHES '') # cmake fails due looking for xcode in the wrong path, thus will be empty var
message(FATAL_ERROR "Xcode 4.3 and higher must be used with cmake 2.8-8 or higher")
endif()
### end cmake incompatibility with xcode 4.3 and higher ###
if(${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4 AND ${XCODE_VERSION} VERSION_LESS 4.3)
# Xcode 4 defaults to the Apple LLVM Compiler.
# Override the default compiler selection because Blender only compiles with gcc up to xcode 4.2
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION})
endif()
else() # unix makefile generator does not fill XCODE_VERSION var, so we get it with a command
execute_process(COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERS_BUILD_NR)
# Convert output to a single line by replacling newlines with spaces.
# This is needed because regex replace can not operate through the newline character
# and applies substitutions for each individual lines.
string(REPLACE "\n" " " XCODE_VERS_BUILD_NR_SINGLE_LINE "${XCODE_VERS_BUILD_NR}")
string(REGEX REPLACE "(.*)Xcode ([0-9\\.]+).*" "\\2" XCODE_VERSION "${XCODE_VERS_BUILD_NR_SINGLE_LINE}")
string(SUBSTRING "${XCODE_VERS_BUILD_NR}" 6 3 XCODE_VERSION) # truncate away build-nr
unset(XCODE_VERS_BUILD_NR)
unset(XCODE_VERS_BUILD_NR_SINGLE_LINE)
endif()
message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_BUNDLE}")
# Older Xcode versions had different approach to the directory hiearchy.
# Require newer Xcode which is also have better chances of being able to compile with the
# required deployment target.
#
# NOTE: Xcode version 8.2 is the latest one which runs on macOS 10.11.
if(${XCODE_VERSION} VERSION_LESS 8.2)
message(FATAL_ERROR "Only Xcode version 8.2 and newer is supported")
endif()
# note: xcode-select path could be ambiguous,
# cause /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed
# so i use a selfcomposed bundlepath here
set(OSX_SYSROOT_PREFIX ${XCODE_BUNDLE}/Contents/Developer/Platforms/MacOSX.platform)
message(STATUS "OSX_SYSROOT_PREFIX: " ${OSX_SYSROOT_PREFIX})
# Collect list of OSX system versions which will be used to detect path to corresponding SDK.
# Start with macOS SDK version reported by xcodebuild and include possible extra ones.
#
# The reason for need of extra ones is because it's possible that xcodebuild will report
# SDK version in the full manner (aka major.minor.patch), but the actual path will only
# include major.minor.
#
# This happens, for example, on macOS Catalina 10.15.4 and Xcode 11.4: xcodebuild on this
# system outputs "10.15.4", but the actual SDK path is MacOSX10.15.sdk.
#
# This should be safe from picking wrong SDK version because (a) xcodebuild reports full semantic
# SDK version, so such SDK does exist on the system. And if it doesn't exist with full version
# in the path, what SDK is in the major.minor folder then.
set(OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM})
if(OSX_SYSTEM MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1.\\2" OSX_SYSTEM_NO_PATCH "${OSX_SYSTEM}")
list(APPEND OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM_NO_PATCH})
unset(OSX_SYSTEM_NO_PATCH)
endif()
# Loop through all possible versions and pick the first one which resolves to a valid SDK path.
set(OSX_SDK_PATH)
set(OSX_SDK_FOUND FALSE)
set(OSX_SDK_PREFIX ${OSX_SYSROOT_PREFIX}/Developer/SDKs)
set(OSX_SDKROOT)
foreach(OSX_SDK_VERSION ${OSX_SDK_TEST_VERSIONS})
set(CURRENT_OSX_SDK_PATH "${OSX_SDK_PREFIX}/MacOSX${OSX_SDK_VERSION}.sdk")
if(EXISTS ${CURRENT_OSX_SDK_PATH})
set(OSX_SDK_PATH "${CURRENT_OSX_SDK_PATH}")
set(OSX_SDKROOT macosx${OSX_SDK_VERSION})
set(OSX_SDK_FOUND TRUE)
break()
if(${XCODE_VERSION} VERSION_LESS 4.3)
# use guaranteed existing sdk
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk CACHE PATH "" FORCE)
else()
# note: xcode-select path could be ambiguous,
# cause /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed
# so i use a selfcomposed bundlepath here
set(OSX_SYSROOT_PREFIX ${XCODE_BUNDLE}/Contents/Developer/Platforms/MacOSX.platform)
message(STATUS "OSX_SYSROOT_PREFIX: " ${OSX_SYSROOT_PREFIX})
set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk
set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE)
if(${CMAKE_GENERATOR} MATCHES "Xcode")
# to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM})
endif()
endforeach()
unset(OSX_SDK_PREFIX)
unset(OSX_SDK_TEST_VERSIONS)
if(NOT OSX_SDK_FOUND)
message(FATAL_ERROR "Unable to find SDK for macOS version ${OSX_SYSTEM}")
endif()
message(STATUS "Detected OSX_SYSROOT: ${OSX_SDK_PATH}")
set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "" FORCE)
unset(OSX_SDK_PATH)
unset(OSX_SDK_FOUND)
if(${CMAKE_GENERATOR} MATCHES "Xcode")
# to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
set(CMAKE_XCODE_ATTRIBUTE_SDKROOT ${OSX_SDKROOT})
endif()
unset(OSX_SDKROOT)
# 10.11 is our min. target, if you use higher sdk, weak linking happens
if(CMAKE_OSX_DEPLOYMENT_TARGET)
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.11)

View File

@@ -195,14 +195,8 @@ endif()
if(WITH_OPENCOLLADA)
find_package_wrapper(OpenCOLLADA)
if(OPENCOLLADA_FOUND)
if(WITH_STATIC_LIBS)
# PCRE is bundled with OpenCollada without headers, so can't use
# find_package reliably to detect it.
set(PCRE_LIBRARIES ${LIBDIR}/opencollada/lib/libpcre.a)
else()
find_package_wrapper(PCRE)
endif()
find_package_wrapper(XML2)
find_package_wrapper(PCRE)
else()
set(WITH_OPENCOLLADA OFF)
endif()
@@ -411,6 +405,13 @@ if(WITH_LLVM)
endif()
endif()
if(WITH_LLVM OR WITH_SDL_DYNLOAD)
# Fix for conflict with Mesa llvmpipe
set(PLATFORM_LINKFLAGS
"${PLATFORM_LINKFLAGS} -Wl,--version-script='${CMAKE_SOURCE_DIR}/source/creator/blender.map'"
)
endif()
if(WITH_OPENSUBDIV)
find_package_wrapper(OpenSubdiv)
@@ -600,16 +601,3 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-intel")
endif()
# Avoid conflicts with Mesa llvmpipe, Luxrender, and other plug-ins that may
# use the same libraries as Blender with a different version or build options.
set(PLATFORM_LINKFLAGS
"${PLATFORM_LINKFLAGS} -Wl,--version-script='${CMAKE_SOURCE_DIR}/source/creator/blender.map'"
)
# Don't use position independent executable for portable install since file
# browsers can't properly detect blender as an executable then. Still enabled
# for non-portable installs as typically used by Linux distributions.
if(WITH_INSTALL_PORTABLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
endif()

View File

@@ -669,7 +669,7 @@ if(WITH_USD)
set(USD_INCLUDE_DIRS ${LIBDIR}/usd/include)
set(USD_RELEASE_LIB ${LIBDIR}/usd/lib/libusd_m.lib)
set(USD_DEBUG_LIB ${LIBDIR}/usd/lib/libusd_m_d.lib)
set(USD_LIBRARY_DIR ${LIBDIR}/usd/lib)
set(USD_LIBRARY_DIR ${LIBDIR}/usd/lib/usd)
set(USD_LIBRARIES
debug ${USD_DEBUG_LIB}
optimized ${USD_RELEASE_LIB}

View File

@@ -6,6 +6,9 @@ if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2019.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2015.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete
echo Compiler Detection failed. Use verbose switch for more information.
exit /b 1

View File

@@ -0,0 +1,3 @@
set BUILD_VS_VER=14
set BUILD_VS_YEAR=2015
call "%~dp0\detect_msvc_classic.cmd"

View File

@@ -0,0 +1,69 @@
if NOT "%verbose%" == "" (
echo Detecting msvc %BUILD_VS_YEAR%
)
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC"
for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C
if DEFINED MSVC_VC_DIR (
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% on Win64 detected at "%MSVC_VC_DIR%"
)
goto msvc_detect_finally
)
REM Check 32 bits
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC"
for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C
if DEFINED MSVC_VC_DIR (
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% on Win32 detected at "%MSVC_VC_DIR%"
)
goto msvc_detect_finally
)
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% not found.
)
goto FAIL
:msvc_detect_finally
set VCVARS=%MSVC_VC_DIR%\vcvarsall.bat
if not exist "%VCVARS%" (
echo "%VCVARS%" not found.
goto FAIL
)
call "%vcvars%" %BUILD_ARCH%
rem try msbuild
msbuild /version > NUL
if errorlevel 1 (
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% msbuild not found
)
goto FAIL
)
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% msbuild found
)
REM try the c++ compiler
cl 2> NUL 1>&2
if errorlevel 1 (
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler not found
)
goto FAIL
)
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler found
)
goto DetectionComplete
:FAIL
exit /b 1
:DetectionComplete
if NOT "%verbose%" == "" (
echo Visual Studio %BUILD_VS_YEAR% Detected successfully
)
exit /b 0

View File

@@ -27,13 +27,7 @@ if NOT "%verbose%" == "" (
if "%VS_InstallDir%"=="" (
if NOT "%verbose%" == "" (
echo.
echo Visual Studio is detected but no suitable installation was found.
echo.
echo Check the "Desktop development with C++" workload has been installed.
echo.
echo If you are attempting to use either Visual Studio Preview version or the Visual C++ Build tools, Please see 'make help' on how to opt in to those toolsets.
echo.
echo Visual Studio is detected but the "Desktop development with C++" workload has not been instlled
goto FAIL
)
)

View File

@@ -66,6 +66,8 @@ if NOT "%1" == "" (
) else if "%1" == "2019b" (
set BUILD_VS_YEAR=2019
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
) else if "%1" == "2015" (
set BUILD_VS_YEAR=2015
) else if "%1" == "packagename" (
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2"
shift /1

View File

@@ -23,17 +23,15 @@ echo - with_tests ^(enable building unit tests^)
echo - nobuildinfo ^(disable buildinfo^)
echo - debug ^(Build an unoptimized debuggable build^)
echo - packagename [newname] ^(override default cpack package name^)
echo - builddir [newdir] ^(override default build folder^)
echo - buildir [newdir] ^(override default build folder^)
echo - 2017 ^(build with visual studio 2017^)
echo - 2017pre ^(build with visual studio 2017 pre-release^)
echo - 2017b ^(build with visual studio 2017 Build Tools^)
echo - 2019 ^(build with visual studio 2019^)
echo - 2019pre ^(build with visual studio 2019 pre-release^)
echo - 2019b ^(build with visual studio 2019 Build Tools^)
echo.
echo Experimental options
echo - with_opengl_tests ^(enable both the render and draw opengl test suites^)
echo - 2015 ^(build with visual studio 2015^)
echo - clang ^(enable building with clang^)
echo - asan ^(enable asan when building with clang^)
echo - ninja ^(enable building with ninja instead of msbuild^)

View File

@@ -2,20 +2,20 @@
Basic Sound Playback
++++++++++++++++++++
This script shows how to use the classes: :class:`Device`, :class:`Sound` and
This script shows how to use the classes: :class:`Device`, :class:`Factory` and
:class:`Handle`.
"""
import aud
device = aud.Device()
device = aud.device()
# load sound file (it can be a video file with audio)
sound = aud.Sound('music.ogg')
factory = aud.Factory('music.ogg')
# play the audio, this return a handle to control play/pause
handle = device.play(sound)
handle = device.play(factory)
# if the audio is not too big and will be used often you can buffer it
sound_buffered = aud.Sound.buffer(sound)
handle_buffered = device.play(sound_buffered)
factory_buffered = aud.Factory.buffer(factory)
handle_buffered = device.play(factory_buffered)
# stop the sounds (otherwise they play until their ends)
handle.stop()

View File

@@ -205,15 +205,15 @@ Support Overview
* - Usage
- :class:`bpy.types.MeshPolygon`
- :class:`bpy.types.MeshLoopTriangle`
- :class:`bpy.types.MeshTessFace`
- :class:`bmesh.types.BMFace`
* - Import/Create
- Poor *(inflexible)*
- Unusable *(read-only)*.
- Good *(supported as upgrade path)*
- Best
* - Manipulate
- Poor *(inflexible)*
- Unusable *(read-only)*.
- Poor *(loses ngons)*
- Best
* - Export/Output
- Good *(ngon support)*

View File

@@ -1052,7 +1052,6 @@ context_type_map = {
"selected_editable_fcurves": ("FCurve", True),
"selected_editable_objects": ("Object", True),
"selected_editable_sequences": ("Sequence", True),
"selected_nla_strips": ("NlaStrip", True),
"selected_nodes": ("Node", True),
"selected_objects": ("Object", True),
"selected_pose_bones": ("PoseBone", True),
@@ -1074,7 +1073,6 @@ context_type_map = {
"visible_pose_bones": ("PoseBone", True),
"visible_fcurves": ("FCurve", True),
"weight_paint_object": ("Object", False),
"volume": ("Volume", False),
"world": ("World", False),
}

View File

@@ -4,51 +4,35 @@ Tutorials
Introduction
------------
The C and Python binding for audaspace were designed with simplicity in mind.
This means however that to use the full capabilities of audaspace,
there is no way around the C++ library.
The C and Python binding for audaspace were designed with simplicity in mind. This means however that to use the full capabilities of audaspace, there is no way around the C++ library.
Simple Demo
-----------
The **simple.py** example program contains all the basic
building blocks for an application using audaspace.
These building blocks are basically the classes :class:`aud.Device`,
:class:`aud.Sound` and :class:`aud.Handle`.
The **simple.py** example program contains all the basic building blocks for an application using audaspace. These building blocks are basically the classes :class:`aud.Device`, :class:`aud.Sound` and :class:`aud.Handle`.
We start with importing :mod:`aud` and :mod:`time`
as the modules we need for our simple example.
We start with importing :mod:`aud` and :mod:`time` as the modules we need for our simple example.
.. code-block:: python
#!/usr/bin/python
import aud, time
The first step now is to open an output device and this
can simply be done by allocating a :class:`aud.Device` object.
The first step now is to open an output device and this can simply be done by allocating a :class:`aud.Device` object.
.. code-block:: python
device = aud.Device()
To create a sound we can choose to load one from a :func:`aud.Sound.file`,
or we use one of our signal generators. We decide to do the latter
and create a :func:`aud.Sound.sine` signal with a frequency of 440 Hz.
To create a sound we can choose to load one from a :func:`aud.Sound.file`, or we use one of our signal generators. We decide to do the latter and create a :func:`aud.Sound.sine` signal with a frequency of 440 Hz.
.. code-block:: python
sine = aud.Sound.sine(440)
.. note:: At this point nothing is playing back yet,
:class:`aud.Sound` objects are just descriptions of sounds.
.. note:: At this point nothing is playing back yet, :class:`aud.Sound` objects are just descriptions of sounds.
However instead of a sine wave, we would like to have a square wave
to produce a more retro gaming sound. We could of course use the
:func:`aud.Sound.square` generator instead of sine,
but we want to show how to apply effects,
so we apply a :func:`aud.Sound.threshold`
which makes a square wave out of our sine too,
even if less efficient than directly generating the square wave.
However instead of a sine wave, we would like to have a square wave to produce a more retro gaming sound. We could of course use the :func:`aud.Sound.square` generator instead of sine, but we want to show how to apply effects, so we apply a :func:`aud.Sound.threshold` which makes a square wave out of our sine too, even if less efficient than directly generating the square wave.
.. code-block:: python
@@ -56,19 +40,13 @@ even if less efficient than directly generating the square wave.
.. note:: The :class:`aud.Sound` class offers generator and effect functions.
The we can play our sound by calling the
:func:`aud.Device.play` method of our device.
This method returns a :class:`aud.Handle`
which is used to control the playback of the sound.
The we can play our sound by calling the :func:`aud.Device.play` method of our device. This method returns a :class:`aud.Handle` which is used to control the playback of the sound.
.. code-block:: python
handle = device.play(square)
Now if we do nothing else anymore the application will quit immediately,
so we won't hear much of our square wave,
so we decide to wait for three seconds before
quitting the application by calling :func:`time.sleep`.
Now if we do nothing else anymore the application will quit immediately, so we won't hear much of our square wave, so we decide to wait for three seconds before quitting the application by calling :func:`time.sleep`.
.. code-block:: python
@@ -77,47 +55,29 @@ quitting the application by calling :func:`time.sleep`.
Audioplayer
-----------
Now that we know the basics of audaspace,
we can build our own music player easily
by just slightly changing the previous program.
The **player.py** example does exactly that,
let's have a short look at the differences:
Now that we know the basics of audaspace, we can build our own music player easily by just slightly changing the previous program. The **player.py** example does exactly that, let's have a short look at the differences:
Instead of creating a sine signal and thresholding it,
we in fact use the :func:`aud.Sound.file` function to load a sound from a file.
The filename we pass is the first command line argument our application got.
Instead of creating a sine signal and thresholding it, we in fact use the :func:`aud.Sound.file` function to load a sound from a file. The filename we pass is the first command line argument our application got.
.. code-block:: python
sound = aud.Sound.file(sys.argv[1])
When the sound gets played back we now want to wait until
the whole file has been played, so we use the :data:`aud.Handle.status`
property to determine whether the sound finished playing.
When the sound gets played back we now want to wait until the whole file has been played, so we use the :data:`aud.Handle.status` property to determine whether the sound finished playing.
.. code-block:: python
while handle.status:
time.sleep(0.1)
We don't make any error checks if the user actually added a command
line argument. As an exercise you could extend this program to play
any number of command line supplied files in sequence.
We don't make any error checks if the user actually added a command line argument. As an exercise you could extend this program to play any number of command line supplied files in sequence.
Siren
-----
Let's get a little bit more complex. The **siren.py** example
plays a generated siren sound that circles around your head.
Depending on how many speakers you have and if the output
device used supports the speaker setup, you will hear this effect.
With stereo speakers you should at least hear some left-right-panning.
Let's get a little bit more complex. The **siren.py** example plays a generated siren sound that circles around your head. Depending on how many speakers you have and if the output device used supports the speaker setup, you will hear this effect. With stereo speakers you should at least hear some left-right-panning.
We start off again with importing the modules we need and
we also define some properties of our siren sound.
We want it to consist of two sine sounds with different frequencies.
We define a length for the sine sounds and how long a fade in/out should take.
We also know already how to open a device.
We start off again with importing the modules we need and we also define some properties of our siren sound. We want it to consist of two sine sounds with different frequencies. We define a length for the sine sounds and how long a fade in/out should take. We also know already how to open a device.
.. code-block:: python
@@ -128,35 +88,27 @@ We also know already how to open a device.
device = aud.Device()
The next thing to do is to define our sine waves and apply all the required effects.
As each of the effect functions returns the corresponding sound,
we can easily chain those calls together.
The next thing to do is to define our sine waves and apply all the required effects. As each of the effect functions returns the corresponding sound, we can easily chain those calls together.
.. code-block:: python
high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
The next step is to connect the two sines,
which we do using the :func:`aud.Sound.join` function.
The next step is to connect the two sines, which we do using the :func:`aud.Sound.join` function.
.. code-block:: python
sound = high.join(low)
The generated siren sound can now be played back and what we also do is to loop it.
Therefore we set the :data:`aud.Handle.loop_count` to a negative value to loop forever.
The generated siren sound can now be played back and what we also do is to loop it. Therefore we set the :data:`aud.Handle.loop_count` to a negative value to loop forever.
.. code-block:: python
handle = device.play(sound)
handle.loop_count = -1
Now we use some timing code to make sure our demo runs for 10 seconds,
but we also use the time to update the location of our playing sound,
with the :data:`aud.Handle.location` property, which is a three dimensional vector.
The trigonometic calculation based on the running time of the program keeps
the sound on the XZ plane letting it follow a circle around us.
Now we use some timing code to make sure our demo runs for 10 seconds, but we also use the time to update the location of our playing sound, with the :data:`aud.Handle.location` property, which is a three dimensional vector. The trigonometic calculation based on the running time of the program keeps the sound on the XZ plane letting it follow a circle around us.
.. code-block:: python
@@ -167,54 +119,33 @@ the sound on the XZ plane letting it follow a circle around us.
handle.location = [math.sin(angle), 0, -math.cos(angle)]
As an exercise you could try to let the sound come from the far left
and go to the far right and a little bit in front of you within the
10 second runtime of the program. With this change you should be able
to hear the volume of the sound change, depending on how far it is away from you.
Updating the :data:`aud.Handle.velocity` property properly also enables the doppler effect.
Compare your solution to the **siren2.py** demo.
As an exercise you could try to let the sound come from the far left and go to the far right and a little bit in front of you within the 10 second runtime of the program. With this change you should be able to hear the volume of the sound change, depending on how far it is away from you. Updating the :data:`aud.Handle.velocity` property properly also enables the doppler effect. Compare your solution to the **siren2.py** demo.
Tetris
------
The **tetris.py** demo application shows an even more
complex application which generates retro tetris music.
Looking at the source code there should be nothing new here,
again the functions used from audaspace are the same as in the previous examples.
In the :func:`parseNote` function all single notes get joined which leads
to a very long chain of sounds. If you think of :func:`aud.Sound.join`
as a function that creates a binary tree with the two joined sounds as
leaves then the :func:`parseNote` function creates a very unbalanced tree.
The **tetris.py** demo application shows an even more complex application which generates retro tetris music. Looking at the source code there should be nothing new here, again the functions used from audaspace are the same as in the previous examples. In the :func:`parseNote` function all single notes get joined which leads to a very long chain of sounds. If you think of :func:`aud.Sound.join` as a function that creates a binary tree with the two joined sounds as leaves then the :func:`parseNote` function creates a very unbalanced tree.
Insted we could rewrite the code to use two other classes:
:class:`aud.Sequence` and :class:`aud.SequenceEntry` to sequence the notes.
The **tetris2.py** application does exactly that.
Before the while loop we add a variable that stores the current position
in the score and create a new :class:`aud.Sequence` object.
Insted we could rewrite the code to use two other classes: :class:`aud.Sequence` and :class:`aud.SequenceEntry` to sequence the notes. The **tetris2.py** application does exactly that. Before the while loop we add a variable that stores the current position in the score and create a new :class:`aud.Sequence` object.
.. code-block:: python
position = 0
sequence = aud.Sequence()
Then in the loop we can create the note simply by chaining the
:func:`aud.Sound.square` generator and :func:`aud.Sound.fadein`
and :func:`aud.Sound.fadeout` effects.
Then in the loop we can create the note simply by chaining the :func:`aud.Sound.square` generator and :func:`aud.Sound.fadein` and :func:`aud.Sound.fadeout` effects.
.. code-block:: python
note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
Now instead of using :func:`aud.Sound.limit` and :func:`aud.Sound.join`
we simply add the sound to the sequence.
Now instead of using :func:`aud.Sound.limit` and :func:`aud.Sound.join` we simply add the sound to the sequence.
.. code-block:: python
entry = sequence.add(note, position, position + length, 0)
The entry returned from the :func:`aud.Sequence.add`
function is an object of the :class:`aud.SequenceEntry` class.
We can use this entry to mute the note in case it's actually a pause.
The entry returned from the :func:`aud.Sequence.add` function is an object of the :class:`aud.SequenceEntry` class. We can use this entry to mute the note in case it's actually a pause.
.. code-block:: python
@@ -227,14 +158,9 @@ Lastly we have to update our position variable.
position += length
Now in **tetris2.py** we used the :data:`aud.SequenceEntry.muted`
property to show how the :class:`aud.SequenceEntry` class can be used,
but it would actually be smarter to not even create a note for pauses and just skip them.
You can try to implement this as an exercise and then check out the solution in **tetris3.py**.
Now in **tetris2.py** we used the :data:`aud.SequenceEntry.muted` property to show how the :class:`aud.SequenceEntry` class can be used, but it would actually be smarter to not even create a note for pauses and just skip them. You can try to implement this as an exercise and then check out the solution in **tetris3.py**.
Conclusion
----------
We introduced all five currently available classes in the audaspace Python API.
Of course all classes offer a lot more functions than have been used in these demo applications,
check out the specific class documentation for more details.
We introduced all five currently available classes in the audaspace Python API. Of course all classes offer a lot more functions than have been used in these demo applications, check out the specific class documentation for more details.

View File

@@ -124,17 +124,15 @@ Device_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Device_lock_doc,
".. classmethod:: lock()\n\n"
" Locks the device so that it's guaranteed, that no samples are\n"
" read from the streams until :meth:`unlock` is called.\n"
" This is useful if you want to do start/stop/pause/resume some\n"
" sounds at the same time.\n\n"
" .. note::\n\n"
" The device has to be unlocked as often as locked to be\n"
" able to continue playback.\n\n"
" .. warning::\n\n"
" Make sure the time between locking and unlocking is\n"
" as short as possible to avoid clicks.");
"lock()\n\n"
"Locks the device so that it's guaranteed, that no samples are "
"read from the streams until :meth:`unlock` is called.\n"
"This is useful if you want to do start/stop/pause/resume some "
"sounds at the same time.\n\n"
".. note:: The device has to be unlocked as often as locked to be "
"able to continue playback.\n\n"
".. warning:: Make sure the time between locking and unlocking is "
"as short as possible to avoid clicks.");
static PyObject *
Device_lock(Device* self)
@@ -152,15 +150,15 @@ Device_lock(Device* self)
}
PyDoc_STRVAR(M_aud_Device_play_doc,
".. classmethod:: play(sound, keep=False)\n\n"
" Plays a sound.\n\n"
" :arg sound: The sound to play.\n"
" :type sound: :class:`Sound`\n"
" :arg keep: See :attr:`Handle.keep`.\n"
" :type keep: bool\n"
" :return: The playback handle with which playback can be\n"
" controlled with.\n"
" :rtype: :class:`Handle`");
"play(sound, keep=False)\n\n"
"Plays a sound.\n\n"
":arg sound: The sound to play.\n"
":type sound: :class:`Sound`\n"
":arg keep: See :attr:`Handle.keep`.\n"
":type keep: bool\n"
":return: The playback handle with which playback can be "
"controlled with.\n"
":rtype: :class:`Handle`");
static PyObject *
Device_play(Device* self, PyObject* args, PyObject* kwds)
@@ -212,8 +210,8 @@ Device_play(Device* self, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Device_stopAll_doc,
".. classmethod:: stopAll()\n\n"
" Stops all playing and paused sounds.");
"stopAll()\n\n"
"Stops all playing and paused sounds.");
static PyObject *
Device_stopAll(Device* self)
@@ -231,9 +229,9 @@ Device_stopAll(Device* self)
}
PyDoc_STRVAR(M_aud_Device_unlock_doc,
".. classmethod:: unlock()\n\n"
" Unlocks the device after a lock call, see :meth:`lock` for\n"
" details.");
"unlock()\n\n"
"Unlocks the device after a lock call, see :meth:`lock` for "
"details.");
static PyObject *
Device_unlock(Device* self)
@@ -286,7 +284,7 @@ Device_get_channels(Device* self, void* nothing)
PyDoc_STRVAR(M_aud_Device_distance_model_doc,
"The distance model of the device.\n\n"
".. seealso:: `OpenAL Documentation <https://www.openal.org/documentation/>`__");
".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
static PyObject *
Device_get_distance_model(Device* self, void* nothing)

View File

@@ -60,12 +60,12 @@ DynamicMusic_dealloc(DynamicMusicP* self)
}
PyDoc_STRVAR(M_aud_DynamicMusic_addScene_doc,
".. classmethod:: addScene(scene)\n\n"
" Adds a new scene.\n\n"
" :arg scene: The scene sound.\n"
" :type scene: :class:`Sound`\n"
" :return: The new scene id.\n"
" :rtype: int");
"addScene(scene)\n\n"
"Adds a new scene.\n\n"
":arg scene: The scene sound.\n"
":type scene: :class:`Sound`\n"
":return: The new scene id.\n"
":rtype: int");
static PyObject *
DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
@@ -90,16 +90,16 @@ DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_DynamicMusic_addTransition_doc,
".. classmethod:: addTransition(ini, end, transition)\n\n"
" Adds a new scene.\n\n"
" :arg ini: the initial scene foor the transition.\n"
" :type ini: int\n"
" :arg end: The final scene for the transition.\n"
" :type end: int\n"
" :arg transition: The transition sound.\n"
" :type transition: :class:`Sound`\n"
" :return: false if the ini or end scenes don't exist, true othrwise.\n"
" :rtype: bool");
"addTransition(ini, end, transition)\n\n"
"Adds a new scene.\n\n"
":arg ini: the initial scene foor the transition.\n"
":type ini: int\n"
":arg end: The final scene for the transition.\n"
":type end: int\n"
":arg transition: The transition sound.\n"
":type transition: :class:`Sound`\n"
":return: false if the ini or end scenes don't exist, true othrwise.\n"
":rtype: bool");
static PyObject *
DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
@@ -125,10 +125,10 @@ DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_DynamicMusic_resume_doc,
".. classmethod:: resume()\n\n"
" Resumes playback of the scene.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"resume()\n\n"
"Resumes playback of the scene.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
DynamicMusic_resume(DynamicMusicP* self)
@@ -145,10 +145,10 @@ DynamicMusic_resume(DynamicMusicP* self)
}
PyDoc_STRVAR(M_aud_DynamicMusic_pause_doc,
".. classmethod:: pause()\n\n"
" Pauses playback of the scene.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"pause()\n\n"
"Pauses playback of the scene.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
DynamicMusic_pause(DynamicMusicP* self)
@@ -165,10 +165,10 @@ DynamicMusic_pause(DynamicMusicP* self)
}
PyDoc_STRVAR(M_aud_DynamicMusic_stop_doc,
".. classmethod:: stop()\n\n"
" Stops playback of the scene.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool\n\n");
"stop()\n\n"
"Stops playback of the scene.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool\n\n");
static PyObject *
DynamicMusic_stop(DynamicMusicP* self)
@@ -464,4 +464,4 @@ void addDynamicMusicToModule(PyObject* module)
{
Py_INCREF(&DynamicMusicType);
PyModule_AddObject(module, "DynamicMusic", (PyObject *)&DynamicMusicType);
}
}

View File

@@ -54,16 +54,16 @@ HRTF_dealloc(HRTFP* self)
}
PyDoc_STRVAR(M_aud_HRTF_addImpulseResponse_doc,
".. classmethod:: addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
" Adds a new hrtf to the HRTF object\n\n"
" :arg sound: The sound that contains the hrtf.\n"
" :type sound: :class:`Sound`\n"
" :arg azimuth: The azimuth angle of the hrtf.\n"
" :type azimuth: float\n"
" :arg elevation: The elevation angle of the hrtf.\n"
" :type elevation: float\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
"Adds a new hrtf to the HRTF object\n\n"
":arg sound: The sound that contains the hrtf.\n"
":type sound: :class:`Sound`\n"
":arg azimuth: The azimuth angle of the hrtf.\n"
":type azimuth: float\n"
":arg elevation: The elevation angle of the hrtf.\n"
":type elevation: float\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
@@ -90,14 +90,14 @@ HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_HRTF_loadLeftHrtfSet_doc,
".. classmethod:: loadLeftHrtfSet(extension, directory)\n\n"
" Loads all HRTFs from a directory.\n\n"
" :arg extension: The file extension of the hrtfs.\n"
" :type extension: string\n"
" :arg directory: The path to where the HRTF files are located.\n"
" :type extension: string\n"
" :return: The loaded :class:`HRTF` object.\n"
" :rtype: :class:`HRTF`\n\n");
"loadLeftHrtfSet(extension, directory)\n\n"
"Loads all HRTFs from a directory.\n\n"
":arg extension: The file extension of the hrtfs.\n"
":type extension: string\n"
":arg directory: The path to where the HRTF files are located.\n"
":type extension: string\n"
":return: The loaded :class:`HRTF` object.\n"
":rtype: :class:`HRTF`\n\n");
static PyObject *
HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
@@ -125,14 +125,14 @@ HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_HRTF_loadRightHrtfSet_doc,
".. classmethod:: loadLeftHrtfSet(extension, directory)\n\n"
" Loads all HRTFs from a directory.\n\n"
" :arg extension: The file extension of the hrtfs.\n"
" :type extension: string\n"
" :arg directory: The path to where the HRTF files are located.\n"
" :type extension: string\n"
" :return: The loaded :class:`HRTF` object.\n"
" :rtype: :class:`HRTF`\n\n");
"loadLeftHrtfSet(extension, directory)\n\n"
"Loads all HRTFs from a directory.\n\n"
":arg extension: The file extension of the hrtfs.\n"
":type extension: string\n"
":arg directory: The path to where the HRTF files are located.\n"
":type extension: string\n"
":return: The loaded :class:`HRTF` object.\n"
":rtype: :class:`HRTF`\n\n");
static PyObject *
HRTF_loadRightHrtfSet(PyTypeObject* type, PyObject* args)

View File

@@ -38,10 +38,10 @@ Handle_dealloc(Handle* self)
}
PyDoc_STRVAR(M_aud_Handle_pause_doc,
".. classmethod:: pause()\n\n"
" Pauses playback.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"pause()\n\n"
"Pauses playback.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
Handle_pause(Handle* self)
@@ -58,10 +58,10 @@ Handle_pause(Handle* self)
}
PyDoc_STRVAR(M_aud_Handle_resume_doc,
".. classmethod:: resume()\n\n"
" Resumes playback.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"resume()\n\n"
"Resumes playback.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
Handle_resume(Handle* self)
@@ -78,11 +78,11 @@ Handle_resume(Handle* self)
}
PyDoc_STRVAR(M_aud_Handle_stop_doc,
".. classmethod:: stop()\n\n"
" Stops playback.\n\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool\n\n"
" .. note:: This makes the handle invalid.");
"stop()\n\n"
"Stops playback.\n\n"
":return: Whether the action succeeded.\n"
":rtype: bool\n\n"
".. note:: This makes the handle invalid.");
static PyObject *
Handle_stop(Handle* self)
@@ -1122,3 +1122,5 @@ void addHandleToModule(PyObject* module)
Py_INCREF(&HandleType);
PyModule_AddObject(module, "Handle", (PyObject *)&HandleType);
}

View File

@@ -60,15 +60,14 @@ PlaybackManager_dealloc(PlaybackManagerP* self)
}
PyDoc_STRVAR(M_aud_PlaybackManager_play_doc,
".. classmethod:: setVolume(sound, catKey)\n\n"
" Plays a sound through the playback manager and assigns it to a category.\n\n"
" :arg sound: The sound to play.\n"
" :type sound: :class:`Sound`\n"
" :arg catKey: the key of the category in which the sound will be added,\n"
" if it doesn't exist, a new one will be created.\n"
" :type catKey: int\n"
" :return: The playback handle with which playback can be controlled with.\n"
" :rtype: :class:`Handle`");
"setVolume(sound, catKey)\n\n"
"Plays a sound through the playback manager and assigns it to a category.\n\n"
":arg sound: The sound to play.\n"
":type sound: :class:`Sound`\n"
":arg catKey: the key of the category in which the sound will be added, if it doesn't exist, a new one will be created.\n"
":type catKey: int\n"
":return: The playback handle with which playback can be controlled with.\n"
":rtype: :class:`Handle`");
static PyObject *
PlaybackManager_play(PlaybackManagerP* self, PyObject* args)
@@ -104,12 +103,12 @@ PlaybackManager_play(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_resume_doc,
".. classmethod:: resume(catKey)\n\n"
" Resumes playback of the catgory.\n\n"
" :arg catKey: the key of the category.\n"
" :type catKey: int\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"resume(catKey)\n\n"
"Resumes playback of the catgory.\n\n"
":arg catKey: the key of the category.\n"
":type catKey: int\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
PlaybackManager_resume(PlaybackManagerP* self, PyObject* args)
@@ -131,12 +130,12 @@ PlaybackManager_resume(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_pause_doc,
".. classmethod:: pause(catKey)\n\n"
" Pauses playback of the category.\n\n"
" :arg catKey: the key of the category.\n"
" :type catKey: int\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool");
"pause(catKey)\n\n"
"Pauses playback of the category.\n\n"
":arg catKey: the key of the category.\n"
":type catKey: int\n"
":return: Whether the action succeeded.\n"
":rtype: bool");
static PyObject *
PlaybackManager_pause(PlaybackManagerP* self, PyObject* args)
@@ -158,12 +157,12 @@ PlaybackManager_pause(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_add_category_doc,
".. classmethod:: addCategory(volume)\n\n"
" Adds a category with a custom volume.\n\n"
" :arg volume: The volume for ther new category.\n"
" :type volume: float\n"
" :return: The key of the new category.\n"
" :rtype: int\n\n");
"addCategory(volume)\n\n"
"Adds a category with a custom volume.\n\n"
":arg volume: The volume for ther new category.\n"
":type volume: float\n"
":return: The key of the new category.\n"
":rtype: int\n\n");
static PyObject *
PlaybackManager_add_category(PlaybackManagerP* self, PyObject* args)
@@ -185,12 +184,12 @@ PlaybackManager_add_category(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_get_volume_doc,
".. classmethod:: getVolume(catKey)\n\n"
" Retrieves the volume of a category.\n\n"
" :arg catKey: the key of the category.\n"
" :type catKey: int\n"
" :return: The volume of the cateogry.\n"
" :rtype: float\n\n");
"getVolume(catKey)\n\n"
"Retrieves the volume of a category.\n\n"
":arg catKey: the key of the category.\n"
":type catKey: int\n"
":return: The volume of the cateogry.\n"
":rtype: float\n\n");
static PyObject *
PlaybackManager_get_volume(PlaybackManagerP* self, PyObject* args)
@@ -212,14 +211,14 @@ PlaybackManager_get_volume(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_set_volume_doc,
".. classmethod:: setVolume(volume, catKey)\n\n"
" Changes the volume of a category.\n\n"
" :arg volume: the new volume value.\n"
" :type volume: float\n"
" :arg catKey: the key of the category.\n"
" :type catKey: int\n"
" :return: Whether the action succeeded.\n"
" :rtype: int\n\n");
"setVolume(volume, catKey)\n\n"
"Changes the volume of a category.\n\n"
":arg volume: the new volume value.\n"
":type volume: float\n"
":arg catKey: the key of the category.\n"
":type catKey: int\n"
":return: Whether the action succeeded.\n"
":rtype: int\n\n");
static PyObject *
PlaybackManager_set_volume(PlaybackManagerP* self, PyObject* args)
@@ -242,12 +241,12 @@ PlaybackManager_set_volume(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_stop_doc,
".. classmethod:: stop(catKey)\n\n"
" Stops playback of the category.\n\n"
" :arg catKey: the key of the category.\n"
" :type catKey: int\n"
" :return: Whether the action succeeded.\n"
" :rtype: bool\n\n");
"stop(catKey)\n\n"
"Stops playback of the category.\n\n"
":arg catKey: the key of the category.\n"
":type catKey: int\n"
":return: Whether the action succeeded.\n"
":rtype: bool\n\n");
static PyObject *
PlaybackManager_stop(PlaybackManagerP* self, PyObject* args)
@@ -269,8 +268,8 @@ PlaybackManager_stop(PlaybackManagerP* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_PlaybackManager_clean_doc,
".. classmethod:: clean()\n\n"
" Cleans all the invalid and finished sound from the playback manager.\n\n");
"clean()\n\n"
"Cleans all the invalid and finished sound from the playback manager.\n\n");
static PyObject *
PlaybackManager_clean(PlaybackManagerP* self)

View File

@@ -99,18 +99,18 @@ Sequence_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Sequence_add_doc,
".. classmethod:: add()\n\n"
" Adds a new entry to the sequence.\n\n"
" :arg sound: The sound this entry should play.\n"
" :type sound: :class:`Sound`\n"
" :arg begin: The start time.\n"
" :type begin: float\n"
" :arg end: The end time or a negative value if determined by the sound.\n"
" :type end: float\n"
" :arg skip: How much seconds should be skipped at the beginning.\n"
" :type skip: float\n"
" :return: The entry added.\n"
" :rtype: :class:`SequenceEntry`");
"add()\n\n"
"Adds a new entry to the sequence.\n\n"
":arg sound: The sound this entry should play.\n"
":type sound: :class:`Sound`\n"
":arg begin: The start time.\n"
":type begin: float\n"
":arg end: The end time or a negative value if determined by the sound.\n"
":type end: float\n"
":arg skip: How much seconds should be skipped at the beginning.\n"
":type skip: float\n"
":return: The entry added.\n"
":rtype: :class:`SequenceEntry`");
static PyObject *
Sequence_add(Sequence* self, PyObject* args, PyObject* kwds)
@@ -151,10 +151,10 @@ Sequence_add(Sequence* self, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Sequence_remove_doc,
".. classmethod:: remove()\n\n"
" Removes an entry from the sequence.\n\n"
" :arg entry: The entry to remove.\n"
" :type entry: :class:`SequenceEntry`\n");
"remove()\n\n"
"Removes an entry from the sequence.\n\n"
":arg entry: The entry to remove.\n"
":type entry: :class:`SequenceEntry`\n");
static PyObject *
Sequence_remove(Sequence* self, PyObject* args)
@@ -183,16 +183,16 @@ Sequence_remove(Sequence* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sequence_setAnimationData_doc,
".. classmethod:: setAnimationData()\n\n"
" Writes animation data to a sequence.\n\n"
" :arg type: The type of animation data.\n"
" :type type: int\n"
" :arg frame: The frame this data is for.\n"
" :type frame: int\n"
" :arg data: The data to write.\n"
" :type data: sequence of float\n"
" :arg animated: Whether the attribute is animated.\n"
" :type animated: bool");
"setAnimationData()\n\n"
"Writes animation data to a sequence.\n\n"
":arg type: The type of animation data.\n"
":type type: int\n"
":arg frame: The frame this data is for.\n"
":type frame: int\n"
":arg data: The data to write.\n"
":type data: sequence of float\n"
":arg animated: Whether the attribute is animated.\n"
":type animated: bool");
static PyObject *
Sequence_setAnimationData(Sequence* self, PyObject* args)
@@ -325,7 +325,7 @@ Sequence_set_channels(Sequence* self, PyObject* args, void* nothing)
PyDoc_STRVAR(M_aud_Sequence_distance_model_doc,
"The distance model of the sequence.\n\n"
".. seealso:: `OpenAL Documentation <https://www.openal.org/documentation/>`__");
".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
static PyObject *
Sequence_get_distance_model(Sequence* self, void* nothing)

View File

@@ -43,14 +43,14 @@ SequenceEntry_dealloc(SequenceEntry* self)
}
PyDoc_STRVAR(M_aud_SequenceEntry_move_doc,
".. classmethod:: move()\n\n"
" Moves the entry.\n\n"
" :arg begin: The new start time.\n"
" :type begin: float\n"
" :arg end: The new end time or a negative value if unknown.\n"
" :type end: float\n"
" :arg skip: How many seconds to skip at the beginning.\n"
" :type skip: float\n");
"move()\n\n"
"Moves the entry.\n\n"
":arg begin: The new start time.\n"
":type begin: float\n"
":arg end: The new end time or a negative value if unknown.\n"
":type end: float\n"
":arg skip: How many seconds to skip at the beginning.\n"
":type skip: float\n");
static PyObject *
SequenceEntry_move(SequenceEntry* self, PyObject* args)
@@ -73,16 +73,16 @@ SequenceEntry_move(SequenceEntry* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_SequenceEntry_setAnimationData_doc,
".. classmethod:: setAnimationData()\n\n"
" Writes animation data to a sequenced entry.\n\n"
" :arg type: The type of animation data.\n"
" :type type: int\n"
" :arg frame: The frame this data is for.\n"
" :type frame: int\n"
" :arg data: The data to write.\n"
" :type data: sequence of float\n"
" :arg animated: Whether the attribute is animated.\n"
" :type animated: bool");
"setAnimationData()\n\n"
"Writes animation data to a sequenced entry.\n\n"
":arg type: The type of animation data.\n"
":type type: int\n"
":arg frame: The frame this data is for.\n"
":type frame: int\n"
":arg data: The data to write.\n"
":type data: sequence of float\n"
":arg animated: Whether the attribute is animated.\n"
":type animated: bool");
static PyObject *
SequenceEntry_setAnimationData(SequenceEntry* self, PyObject* args)

View File

@@ -114,11 +114,11 @@ Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Sound_data_doc,
".. classmethod:: data()\n\n"
" Retrieves the data of the sound as numpy array.\n\n"
" :return: A two dimensional numpy float array.\n"
" :rtype: :class:`numpy.ndarray`\n\n"
" .. note:: Best efficiency with cached sounds.");
"data()\n\n"
"Retrieves the data of the sound as numpy array.\n\n"
":return: A two dimensional numpy float array.\n"
":rtype: :class:`numpy.ndarray`\n\n"
".. note:: Best efficiency with cached sounds.");
static PyObject *
Sound_data(Sound* self)
@@ -145,24 +145,24 @@ Sound_data(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_write_doc,
".. classmethod:: write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
" Writes the sound to a file.\n\n"
" :arg filename: The path to write to.\n"
" :type filename: string\n"
" :arg rate: The sample rate to write with.\n"
" :type rate: int\n"
" :arg channels: The number of channels to write with.\n"
" :type channels: int\n"
" :arg format: The sample format to write with.\n"
" :type format: int\n"
" :arg container: The container format for the file.\n"
" :type container: int\n"
" :arg codec: The codec to use in the file.\n"
" :type codec: int\n"
" :arg bitrate: The bitrate to write with.\n"
" :type bitrate: int\n"
" :arg buffersize: The size of the writing buffer.\n"
" :type buffersize: int");
"write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
"Writes the sound to a file.\n\n"
":arg filename: The path to write to.\n"
":type filename: string\n"
":arg rate: The sample rate to write with.\n"
":type rate: int\n"
":arg channels: The number of channels to write with.\n"
":type channels: int\n"
":arg format: The sample format to write with.\n"
":type format: int\n"
":arg container: The container format for the file.\n"
":type container: int\n"
":arg codec: The codec to use in the file.\n"
":type codec: int\n"
":arg bitrate: The bitrate to write with.\n"
":type bitrate: int\n"
":arg buffersize: The size of the writing buffer.\n"
":type buffersize: int\n");
static PyObject *
Sound_write(Sound* self, PyObject* args, PyObject* kwds)
@@ -286,14 +286,14 @@ Sound_write(Sound* self, PyObject* args, PyObject* kwds)
}
PyDoc_STRVAR(M_aud_Sound_buffer_doc,
".. classmethod:: buffer(data, rate)\n\n"
" Creates a sound from a data buffer.\n\n"
" :arg data: The data as two dimensional numpy array.\n"
" :type data: numpy.ndarray\n"
" :arg rate: The sample rate.\n"
" :type rate: double\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"buffer(data, rate)\n\n"
"Creates a sound from a data buffer.\n\n"
":arg data: The data as two dimensional numpy array.\n"
":type data: numpy.ndarray\n"
":arg rate: The sample rate.\n"
":type rate: double\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_buffer(PyTypeObject* type, PyObject* args)
@@ -356,17 +356,16 @@ Sound_buffer(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_cache_doc,
".. classmethod:: cache()\n\n"
" Caches a sound into RAM.\n\n"
" This saves CPU usage needed for decoding and file access if the\n"
" underlying sound reads from a file on the harddisk,\n"
" but it consumes a lot of memory.\n\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note:: Only known-length factories can be buffered.\n\n"
" .. warning::\n\n"
" Raw PCM data needs a lot of space, only buffer\n"
" short factories.");
"cache()\n\n"
"Caches a sound into RAM.\n"
"This saves CPU usage needed for decoding and file access if the "
"underlying sound reads from a file on the harddisk, but it "
"consumes a lot of memory.\n\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: Only known-length factories can be buffered.\n\n"
".. warning:: Raw PCM data needs a lot of space, only buffer "
"short factories.");
static PyObject *
Sound_cache(Sound* self)
@@ -392,16 +391,15 @@ Sound_cache(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_file_doc,
".. classmethod:: file(filename)\n\n"
" Creates a sound object of a sound file.\n\n"
" :arg filename: Path of the file.\n"
" :type filename: string\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. warning::\n\n"
" If the file doesn't exist or can't be read you will\n"
" not get an exception immediately, but when you try to start\n"
" playback of that sound.\n");
"file(filename)\n\n"
"Creates a sound object of a sound file.\n\n"
":arg filename: Path of the file.\n"
":type filename: string\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. warning:: If the file doesn't exist or can't be read you will "
"not get an exception immediately, but when you try to start "
"playback of that sound.");
static PyObject *
Sound_file(PyTypeObject* type, PyObject* args)
@@ -432,15 +430,15 @@ Sound_file(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_sawtooth_doc,
".. classmethod:: sawtooth(frequency, rate=48000)\n\n"
" Creates a sawtooth sound which plays a sawtooth wave.\n\n"
" :arg frequency: The frequency of the sawtooth wave in Hz.\n"
" :type frequency: float\n"
" :arg rate: The sampling rate in Hz. It's recommended to set this\n"
" value to the playback device's samling rate to avoid resamping.\n"
" :type rate: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"sawtooth(frequency, rate=48000)\n\n"
"Creates a sawtooth sound which plays a sawtooth wave.\n\n"
":arg frequency: The frequency of the sawtooth wave in Hz.\n"
":type frequency: float\n"
":arg rate: The sampling rate in Hz. It's recommended to set this "
"value to the playback device's samling rate to avoid resamping.\n"
":type rate: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_sawtooth(PyTypeObject* type, PyObject* args)
@@ -472,13 +470,13 @@ Sound_sawtooth(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_silence_doc,
".. classmethod:: silence(rate=48000)\n\n"
" Creates a silence sound which plays simple silence.\n\n"
" :arg rate: The sampling rate in Hz. It's recommended to set this\n"
" value to the playback device's samling rate to avoid resamping.\n"
" :type rate: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"silence(rate=48000)\n\n"
"Creates a silence sound which plays simple silence.\n\n"
":arg rate: The sampling rate in Hz. It's recommended to set this "
"value to the playback device's samling rate to avoid resamping.\n"
":type rate: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_silence(PyTypeObject* type, PyObject* args)
@@ -509,15 +507,15 @@ Sound_silence(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_sine_doc,
".. classmethod:: sine(frequency, rate=48000)\n\n"
" Creates a sine sound which plays a sine wave.\n\n"
" :arg frequency: The frequency of the sine wave in Hz.\n"
" :type frequency: float\n"
" :arg rate: The sampling rate in Hz. It's recommended to set this\n"
" value to the playback device's samling rate to avoid resamping.\n"
" :type rate: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"sine(frequency, rate=48000)\n\n"
"Creates a sine sound which plays a sine wave.\n\n"
":arg frequency: The frequency of the sine wave in Hz.\n"
":type frequency: float\n"
":arg rate: The sampling rate in Hz. It's recommended to set this "
"value to the playback device's samling rate to avoid resamping.\n"
":type rate: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_sine(PyTypeObject* type, PyObject* args)
@@ -549,15 +547,15 @@ Sound_sine(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_square_doc,
".. classmethod:: square(frequency, rate=48000)\n\n"
" Creates a square sound which plays a square wave.\n\n"
" :arg frequency: The frequency of the square wave in Hz.\n"
" :type frequency: float\n"
" :arg rate: The sampling rate in Hz. It's recommended to set this\n"
" value to the playback device's samling rate to avoid resamping.\n"
" :type rate: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"square(frequency, rate=48000)\n\n"
"Creates a square sound which plays a square wave.\n\n"
":arg frequency: The frequency of the square wave in Hz.\n"
":type frequency: float\n"
":arg rate: The sampling rate in Hz. It's recommended to set this "
"value to the playback device's samling rate to avoid resamping.\n"
":type rate: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_square(PyTypeObject* type, PyObject* args)
@@ -589,15 +587,15 @@ Sound_square(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_triangle_doc,
".. classmethod:: triangle(frequency, rate=48000)\n\n"
" Creates a triangle sound which plays a triangle wave.\n\n"
" :arg frequency: The frequency of the triangle wave in Hz.\n"
" :type frequency: float\n"
" :arg rate: The sampling rate in Hz. It's recommended to set this\n"
" value to the playback device's samling rate to avoid resamping.\n"
" :type rate: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"triangle(frequency, rate=48000)\n\n"
"Creates a triangle sound which plays a triangle wave.\n\n"
":arg frequency: The frequency of the triangle wave in Hz.\n"
":type frequency: float\n"
":arg rate: The sampling rate in Hz. It's recommended to set this "
"value to the playback device's samling rate to avoid resamping.\n"
":type rate: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_triangle(PyTypeObject* type, PyObject* args)
@@ -629,16 +627,14 @@ Sound_triangle(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_accumulate_doc,
".. classmethod:: accumulate(additive=False)\n\n"
" Accumulates a sound by summing over positive input\n"
" differences thus generating a monotonic sigal.\n"
" If additivity is set to true negative input differences get added too,\n"
" but positive ones with a factor of two.\n\n"
" Note that with additivity the signal is not monotonic anymore.\n\n"
" :arg additive: Whether the accumulation should be additive or not.\n"
" :type time: bool\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"accumulate(additive=False)\n\n"
"Accumulates a sound by summing over positive input differences thus generating a monotonic sigal. "
"If additivity is set to true negative input differences get added too, but positive ones with a factor of two. "
"Note that with additivity the signal is not monotonic anymore.\n\n"
":arg additive: Whether the accumulation should be additive or not.\n"
":type time: bool\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_accumulate(Sound* self, PyObject* args)
@@ -681,19 +677,19 @@ Sound_accumulate(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_ADSR_doc,
".. classmethod:: ADSR(attack, decay, sustain, release)\n\n"
" Attack-Decay-Sustain-Release envelopes the volume of a sound.\n"
" Note: there is currently no way to trigger the release with this API.\n\n"
" :arg attack: The attack time in seconds.\n"
" :type attack: float\n"
" :arg decay: The decay time in seconds.\n"
" :type decay: float\n"
" :arg sustain: The sustain level.\n"
" :type sustain: float\n"
" :arg release: The release level.\n"
" :type release: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"ADSR(attack,decay,sustain,release)\n\n"
"Attack-Decay-Sustain-Release envelopes the volume of a sound. "
"Note: there is currently no way to trigger the release with this API.\n\n"
":arg attack: The attack time in seconds.\n"
":type attack: float\n"
":arg decay: The decay time in seconds.\n"
":type decay: float\n"
":arg sustain: The sustain level.\n"
":type sustain: float\n"
":arg release: The release level.\n"
":type release: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_ADSR(Sound* self, PyObject* args)
@@ -724,12 +720,14 @@ Sound_ADSR(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_delay_doc,
".. classmethod:: delay(time)\n\n"
" Delays by playing adding silence in front of the other sound's data.\n\n"
" :arg time: How many seconds of silence should be added before the sound.\n"
" :type time: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"delay(time)\n\n"
"Delays by playing adding silence in front of the other sound's "
"data.\n\n"
":arg time: How many seconds of silence should be added before "
"the sound.\n"
":type time: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_delay(Sound* self, PyObject* args)
@@ -760,18 +758,19 @@ Sound_delay(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_envelope_doc,
".. classmethod:: envelope(attack, release, threshold, arthreshold)\n\n"
" Delays by playing adding silence in front of the other sound's data.\n\n"
" :arg attack: The attack factor.\n"
" :type attack: float\n"
" :arg release: The release factor.\n"
" :type release: float\n"
" :arg threshold: The general threshold value.\n"
" :type threshold: float\n"
" :arg arthreshold: The attack/release threshold value.\n"
" :type arthreshold: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"envelope(attack, release, threshold, arthreshold)\n\n"
"Delays by playing adding silence in front of the other sound's "
"data.\n\n"
":arg attack: The attack factor.\n"
":type attack: float\n"
":arg release: The release factor.\n"
":type release: float\n"
":arg threshold: The general threshold value.\n"
":type threshold: float\n"
":arg arthreshold: The attack/release threshold value.\n"
":type arthreshold: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_envelope(Sound* self, PyObject* args)
@@ -802,16 +801,16 @@ Sound_envelope(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_fadein_doc,
".. classmethod:: fadein(start, length)\n\n"
" Fades a sound in by raising the volume linearly in the given\n"
" time interval.\n\n"
" :arg start: Time in seconds when the fading should start.\n"
" :type start: float\n"
" :arg length: Time in seconds how long the fading should last.\n"
" :type length: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note:: Before the fade starts it plays silence.");
"fadein(start, length)\n\n"
"Fades a sound in by raising the volume linearly in the given "
"time interval.\n\n"
":arg start: Time in seconds when the fading should start.\n"
":type start: float\n"
":arg length: Time in seconds how long the fading should last.\n"
":type length: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: Before the fade starts it plays silence.");
static PyObject *
Sound_fadein(Sound* self, PyObject* args)
@@ -842,18 +841,17 @@ Sound_fadein(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
".. classmethod:: fadeout(start, length)\n\n"
" Fades a sound in by lowering the volume linearly in the given\n"
" time interval.\n\n"
" :arg start: Time in seconds when the fading should start.\n"
" :type start: float\n"
" :arg length: Time in seconds how long the fading should last.\n"
" :type length: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" After the fade this sound plays silence, so that\n"
" the length of the sound is not altered.");
"fadeout(start, length)\n\n"
"Fades a sound in by lowering the volume linearly in the given "
"time interval.\n\n"
":arg start: Time in seconds when the fading should start.\n"
":type start: float\n"
":arg length: Time in seconds how long the fading should last.\n"
":type length: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: After the fade this sound plays silence, so that "
"the length of the sound is not altered.");
static PyObject *
Sound_fadeout(Sound* self, PyObject* args)
@@ -884,20 +882,20 @@ Sound_fadeout(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_filter_doc,
".. classmethod:: filter(b, a = (1))\n\n"
" Filters a sound with the supplied IIR filter coefficients.\n"
" Without the second parameter you'll get a FIR filter.\n\n"
" If the first value of the a sequence is 0,\n"
" it will be set to 1 automatically.\n"
" If the first value of the a sequence is neither 0 nor 1, all\n"
" filter coefficients will be scaled by this value so that it is 1\n"
" in the end, you don't have to scale yourself.\n\n"
" :arg b: The nominator filter coefficients.\n"
" :type b: sequence of float\n"
" :arg a: The denominator filter coefficients.\n"
" :type a: sequence of float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"filter(b, a = (1))\n\n"
"Filters a sound with the supplied IIR filter coefficients.\n"
"Without the second parameter you'll get a FIR filter.\n"
"If the first value of the a sequence is 0 it will be set to 1 "
"automatically.\n"
"If the first value of the a sequence is neither 0 nor 1, all "
"filter coefficients will be scaled by this value so that it is 1 "
"in the end, you don't have to scale yourself.\n\n"
":arg b: The nominator filter coefficients.\n"
":type b: sequence of float\n"
":arg a: The denominator filter coefficients.\n"
":type a: sequence of float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_filter(Sound* self, PyObject* args)
@@ -984,15 +982,15 @@ Sound_filter(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_highpass_doc,
".. classmethod:: highpass(frequency, Q=0.5)\n\n"
" Creates a second order highpass filter based on the transfer\n"
" function :math:`H(s) = s^2 / (s^2 + s/Q + 1)`\n\n"
" :arg frequency: The cut off trequency of the highpass.\n"
" :type frequency: float\n"
" :arg Q: Q factor of the lowpass.\n"
" :type Q: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"highpass(frequency, Q=0.5)\n\n"
"Creates a second order highpass filter based on the transfer "
"function H(s) = s^2 / (s^2 + s/Q + 1)\n\n"
":arg frequency: The cut off trequency of the highpass.\n"
":type frequency: float\n"
":arg Q: Q factor of the lowpass.\n"
":type Q: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_highpass(Sound* self, PyObject* args)
@@ -1024,14 +1022,14 @@ Sound_highpass(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_limit_doc,
".. classmethod:: limit(start, end)\n\n"
" Limits a sound within a specific start and end time.\n\n"
" :arg start: Start time in seconds.\n"
" :type start: float\n"
" :arg end: End time in seconds.\n"
" :type end: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"limit(start, end)\n\n"
"Limits a sound within a specific start and end time.\n\n"
":arg start: Start time in seconds.\n"
":type start: float\n"
":arg end: End time in seconds.\n"
":type end: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_limit(Sound* self, PyObject* args)
@@ -1062,16 +1060,15 @@ Sound_limit(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_loop_doc,
".. classmethod:: loop(count)\n\n"
" Loops a sound.\n\n"
" :arg count: How often the sound should be looped.\n"
" Negative values mean endlessly.\n"
" :type count: integer\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" This is a filter function, you might consider using\n"
" :attr:`Handle.loop_count` instead.");
"loop(count)\n\n"
"Loops a sound.\n\n"
":arg count: How often the sound should be looped. "
"Negative values mean endlessly.\n"
":type count: integer\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: This is a filter function, you might consider using "
":attr:`Handle.loop_count` instead.");
static PyObject *
Sound_loop(Sound* self, PyObject* args)
@@ -1102,15 +1099,15 @@ Sound_loop(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
".. classmethod:: lowpass(frequency, Q=0.5)\n\n"
" Creates a second order lowpass filter based on the transfer "
" function :math:`H(s) = 1 / (s^2 + s/Q + 1)`\n\n"
" :arg frequency: The cut off trequency of the lowpass.\n"
" :type frequency: float\n"
" :arg Q: Q factor of the lowpass.\n"
" :type Q: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"lowpass(frequency, Q=0.5)\n\n"
"Creates a second order lowpass filter based on the transfer "
"function H(s) = 1 / (s^2 + s/Q + 1)\n\n"
":arg frequency: The cut off trequency of the lowpass.\n"
":type frequency: float\n"
":arg Q: Q factor of the lowpass.\n"
":type Q: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_lowpass(Sound* self, PyObject* args)
@@ -1142,15 +1139,14 @@ Sound_lowpass(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_modulate_doc,
".. classmethod:: modulate(sound)\n\n"
" Modulates two factories.\n\n"
" :arg sound: The sound to modulate over the other.\n"
" :type sound: :class:`Sound`\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" The two factories have to have the same specifications\n"
" (channels and samplerate).");
"modulate(sound)\n\n"
"Modulates two factories.\n\n"
":arg sound: The sound to modulate over the other.\n"
":type sound: :class:`Sound`\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: The two factories have to have the same specifications "
"(channels and samplerate).");
static PyObject *
Sound_modulate(Sound* self, PyObject* object)
@@ -1184,19 +1180,17 @@ Sound_modulate(Sound* self, PyObject* object)
}
PyDoc_STRVAR(M_aud_Sound_pitch_doc,
".. classmethod:: pitch(factor)\n\n"
" Changes the pitch of a sound with a specific factor.\n\n"
" :arg factor: The factor to change the pitch with.\n"
" :type factor: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" This is done by changing the sample rate of the\n"
" underlying sound, which has to be an integer, so the factor\n"
" value rounded and the factor may not be 100 % accurate.\n\n"
" .. note::\n\n"
" This is a filter function, you might consider using\n"
" :attr:`Handle.pitch` instead.");
"pitch(factor)\n\n"
"Changes the pitch of a sound with a specific factor.\n\n"
":arg factor: The factor to change the pitch with.\n"
":type factor: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: This is done by changing the sample rate of the "
"underlying sound, which has to be an integer, so the factor "
"value rounded and the factor may not be 100 % accurate.\n\n"
".. note:: This is a filter function, you might consider using "
":attr:`Handle.pitch` instead.");
static PyObject *
Sound_pitch(Sound* self, PyObject* args)
@@ -1227,12 +1221,12 @@ Sound_pitch(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_rechannel_doc,
".. classmethod:: rechannel(channels)\n\n"
" Rechannels the sound.\n\n"
" :arg channels: The new channel configuration.\n"
" :type channels: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"rechannel(channels)\n\n"
"Rechannels the sound.\n\n"
":arg channels: The new channel configuration.\n"
":type channels: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_rechannel(Sound* self, PyObject* args)
@@ -1267,14 +1261,14 @@ Sound_rechannel(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_resample_doc,
".. classmethod:: resample(rate, high_quality)\n\n"
" Resamples the sound.\n\n"
" :arg rate: The new sample rate.\n"
" :type rate: double\n"
" :arg high_quality: When true use a higher quality but slower resampler.\n"
" :type high_quality: bool\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"resample(rate, high_quality)\n\n"
"Resamples the sound.\n\n"
":arg rate: The new sample rate.\n"
":type rate: double\n"
":arg high_quality: When true use a higher quality but slower resampler.\n"
":type high_quality: bool\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_resample(Sound* self, PyObject* args)
@@ -1322,19 +1316,17 @@ Sound_resample(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_reverse_doc,
".. classmethod:: reverse()\n\n"
" Plays a sound reversed.\n\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" The sound has to have a finite length and has to be seekable.\n"
" It's recommended to use this only with factories with\n"
" fast and accurate seeking, which is not true for encoded audio\n"
" files, such ones should be buffered using :meth:`cache` before\n"
" being played reversed.\n\n"
" .. warning::\n\n"
" If seeking is not accurate in the underlying sound\n"
" you'll likely hear skips/jumps/cracks.");
"reverse()\n\n"
"Plays a sound reversed.\n\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: The sound has to have a finite length and has to be "
"seekable. It's recommended to use this only with factories with "
"fast and accurate seeking, which is not true for encoded audio "
"files, such ones should be buffered using :meth:`cache` before "
"being played reversed.\n\n"
".. warning:: If seeking is not accurate in the underlying sound "
"you'll likely hear skips/jumps/cracks.");
static PyObject *
Sound_reverse(Sound* self)
@@ -1360,10 +1352,10 @@ Sound_reverse(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_sum_doc,
".. classmethod:: sum()\n\n"
" Sums the samples of a sound.\n\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"sum()\n\n"
"Sums the samples of a sound.\n\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_sum(Sound* self)
@@ -1389,12 +1381,12 @@ Sound_sum(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_threshold_doc,
".. classmethod:: threshold(threshold = 0)\n\n"
" Makes a threshold wave out of an audio wave by setting all samples\n"
" with a amplitude >= threshold to 1, all <= -threshold to -1 and\n"
" all between to 0.\n\n"
" :arg threshold: Threshold value over which an amplitude counts\n"
" non-zero.\n"
"threshold(threshold = 0)\n\n"
"Makes a threshold wave out of an audio wave by setting all samples "
"with a amplitude >= threshold to 1, all <= -threshold to -1 and "
"all between to 0.\n\n"
":arg threshold: Threshold value over which an amplitude counts "
"non-zero.\n"
":type threshold: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
@@ -1428,16 +1420,15 @@ Sound_threshold(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_volume_doc,
".. classmethod:: volume(volume)\n\n"
" Changes the volume of a sound.\n\n"
" :arg volume: The new volume..\n"
" :type volume: float\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
" .. note::\n\n"
" This is a filter function, you might consider using\n"
" :attr:`Handle.volume` instead.");
"volume(volume)\n\n"
"Changes the volume of a sound.\n\n"
":arg volume: The new volume..\n"
":type volume: float\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
".. note:: This is a filter function, you might consider using "
":attr:`Handle.volume` instead.");
static PyObject *
Sound_volume(Sound* self, PyObject* args)
@@ -1468,15 +1459,14 @@ Sound_volume(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_join_doc,
".. classmethod:: join(sound)\n\n"
" Plays two factories in sequence.\n\n"
" :arg sound: The sound to play second.\n"
" :type sound: :class:`Sound`\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" The two factories have to have the same specifications\n"
" (channels and samplerate).");
"join(sound)\n\n"
"Plays two factories in sequence.\n\n"
":arg sound: The sound to play second.\n"
":type sound: :class:`Sound`\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: The two factories have to have the same specifications "
"(channels and samplerate).");
static PyObject *
Sound_join(Sound* self, PyObject* object)
@@ -1511,15 +1501,14 @@ Sound_join(Sound* self, PyObject* object)
}
PyDoc_STRVAR(M_aud_Sound_mix_doc,
".. classmethod:: mix(sound)\n\n"
" Mixes two factories.\n\n"
" :arg sound: The sound to mix over the other.\n"
" :type sound: :class:`Sound`\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`\n\n"
" .. note::\n\n"
" The two factories have to have the same specifications\n"
" (channels and samplerate).");
"mix(sound)\n\n"
"Mixes two factories.\n\n"
":arg sound: The sound to mix over the other.\n"
":type sound: :class:`Sound`\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`\n\n"
".. note:: The two factories have to have the same specifications "
"(channels and samplerate).");
static PyObject *
Sound_mix(Sound* self, PyObject* object)
@@ -1553,11 +1542,11 @@ Sound_mix(Sound* self, PyObject* object)
}
PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
".. classmethod:: pingpong()\n\n"
" Plays a sound forward and then backward.\n"
" This is like joining a sound with its reverse.\n\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"pingpong()\n\n"
"Plays a sound forward and then backward.\n"
"This is like joining a sound with its reverse.\n\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_pingpong(Sound* self)
@@ -1583,12 +1572,12 @@ Sound_pingpong(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_list_doc,
".. classmethod:: list()\n\n"
" Creates an empty sound list that can contain several sounds.\n\n"
" :arg random: whether the playback will be random or not.\n"
" :type random: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"list()\n\n"
"Creates an empty sound list that can contain several sounds.\n\n"
":arg random: wether the playback will be random or not.\n"
":type random: int\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_list(PyTypeObject* type, PyObject* args)
@@ -1619,11 +1608,11 @@ Sound_list(PyTypeObject* type, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_mutable_doc,
".. classmethod:: mutable()\n\n"
" Creates a sound that will be restarted when sought backwards.\n"
" If the original sound is a sound list, the playing sound can change.\n\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"mutable()\n\n"
"Creates a sound that will be restarted when sought backwards.\n"
"If the original sound is a sound list, the playing sound can change.\n\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_mutable(Sound* self)
@@ -1649,12 +1638,12 @@ Sound_mutable(Sound* self)
}
PyDoc_STRVAR(M_aud_Sound_list_addSound_doc,
".. classmethod:: addSound(sound)\n\n"
" Adds a new sound to a sound list.\n\n"
" :arg sound: The sound that will be added to the list.\n"
" :type sound: :class:`Sound`\n\n"
" .. note:: You can only add a sound to a sound list.");
"addSound(sound)\n\n"
"Adds a new sound to a sound list.\n\n"
":arg sound: The sound that will be added to the list.\n"
":type sound: :class:`Sound`\n\n"
".. note:: You can only add a sound to a sound list.");
static PyObject *
Sound_list_addSound(Sound* self, PyObject* object)
{
@@ -1682,14 +1671,14 @@ Sound_list_addSound(Sound* self, PyObject* object)
#ifdef WITH_CONVOLUTION
PyDoc_STRVAR(M_aud_Sound_convolver_doc,
".. classmethod:: convolver()\n\n"
" Creates a sound that will apply convolution to another sound.\n\n"
" :arg impulseResponse: The filter with which convolve the sound.\n"
" :type impulseResponse: :class:`ImpulseResponse`\n"
" :arg threadPool: A thread pool used to parallelize convolution.\n"
" :type threadPool: :class:`ThreadPool`\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"convolver()\n\n"
"Creates a sound that will apply convolution to another sound.\n\n"
":arg impulseResponse: The filter with which convolve the sound.\n"
":type impulseResponse: :class:`ImpulseResponse`\n"
":arg threadPool: A thread pool used to parallelize convolution.\n"
":type threadPool: :class:`ThreadPool`\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_convolver(Sound* self, PyObject* args)
@@ -1731,16 +1720,16 @@ Sound_convolver(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_binaural_doc,
".. classmethod:: convolver()\n\n"
" Creates a binaural sound using another sound as source. The original sound must be mono\n\n"
" :arg hrtfs: An HRTF set.\n"
" :type hrtf: :class:`HRTF`\n"
" :arg source: An object representing the source position of the sound.\n"
" :type source: :class:`Source`\n"
" :arg threadPool: A thread pool used to parallelize convolution.\n"
" :type threadPool: :class:`ThreadPool`\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
"convolver()\n\n"
"Creates a binaural sound using another sound as source. The original sound must be mono\n\n"
":arg hrtfs: An HRTF set.\n"
":type hrtf: :class:`HRTF`\n"
":arg source: An object representing the source position of the sound.\n"
":type source: :class:`Source`\n"
":arg threadPool: A thread pool used to parallelize convolution.\n"
":type threadPool: :class:`ThreadPool`\n"
":return: The created :class:`Sound` object.\n"
":rtype: :class:`Sound`");
static PyObject *
Sound_binaural(Sound* self, PyObject* args)

View File

@@ -71,7 +71,7 @@ rm $BLENDER_INSTALLATION/blender/tmp/preprocessed/fileio/*.reg
cd $BLENDER_INSTALLATION/blender/tmp/
echo "Applying clang format to Mantaflow source files"
find . -iname *.h -o -iname *.cpp | xargs clang-format --verbose -i -style=file -sort-includes=0
find . -iname *.h -o -iname *.cpp | xargs clang-format --verbose -i -style=file
find . -iname *.h -o -iname *.cpp | xargs dos2unix --verbose
# ==================== 5) MOVE MANTAFLOW FILES TO EXTERN/ ================================

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit 21303fab2eda588ec22988bf9e5762d2001c131f"
#define MANTA_GIT_VERSION "commit 5fbd3d04381b21afce4a593d1fe2d9bc7bef5424"

View File

@@ -853,147 +853,6 @@ template<class T> struct knPermuteAxes : public KernelBase {
int axis2;
};
struct knJoinVec : public KernelBase {
knJoinVec(Grid<Vec3> &a, const Grid<Vec3> &b, bool keepMax)
: KernelBase(&a, 0), a(a), b(b), keepMax(keepMax)
{
runMessage();
run();
}
inline void op(IndexInt idx, Grid<Vec3> &a, const Grid<Vec3> &b, bool keepMax) const
{
Real a1 = normSquare(a[idx]);
Real b1 = normSquare(b[idx]);
a[idx] = (keepMax) ? max(a1, b1) : min(a1, b1);
}
inline Grid<Vec3> &getArg0()
{
return a;
}
typedef Grid<Vec3> type0;
inline const Grid<Vec3> &getArg1()
{
return b;
}
typedef Grid<Vec3> type1;
inline bool &getArg2()
{
return keepMax;
}
typedef bool type2;
void runMessage()
{
debMsg("Executing kernel knJoinVec ", 3);
debMsg("Kernel range"
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
op(idx, a, b, keepMax);
}
void run()
{
tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this);
}
Grid<Vec3> &a;
const Grid<Vec3> &b;
bool keepMax;
};
struct knJoinInt : public KernelBase {
knJoinInt(Grid<int> &a, const Grid<int> &b, bool keepMax)
: KernelBase(&a, 0), a(a), b(b), keepMax(keepMax)
{
runMessage();
run();
}
inline void op(IndexInt idx, Grid<int> &a, const Grid<int> &b, bool keepMax) const
{
a[idx] = (keepMax) ? max(a[idx], b[idx]) : min(a[idx], b[idx]);
}
inline Grid<int> &getArg0()
{
return a;
}
typedef Grid<int> type0;
inline const Grid<int> &getArg1()
{
return b;
}
typedef Grid<int> type1;
inline bool &getArg2()
{
return keepMax;
}
typedef bool type2;
void runMessage()
{
debMsg("Executing kernel knJoinInt ", 3);
debMsg("Kernel range"
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
op(idx, a, b, keepMax);
}
void run()
{
tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this);
}
Grid<int> &a;
const Grid<int> &b;
bool keepMax;
};
struct knJoinReal : public KernelBase {
knJoinReal(Grid<Real> &a, const Grid<Real> &b, bool keepMax)
: KernelBase(&a, 0), a(a), b(b), keepMax(keepMax)
{
runMessage();
run();
}
inline void op(IndexInt idx, Grid<Real> &a, const Grid<Real> &b, bool keepMax) const
{
a[idx] = (keepMax) ? max(a[idx], b[idx]) : min(a[idx], b[idx]);
}
inline Grid<Real> &getArg0()
{
return a;
}
typedef Grid<Real> type0;
inline const Grid<Real> &getArg1()
{
return b;
}
typedef Grid<Real> type1;
inline bool &getArg2()
{
return keepMax;
}
typedef bool type2;
void runMessage()
{
debMsg("Executing kernel knJoinReal ", 3);
debMsg("Kernel range"
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
op(idx, a, b, keepMax);
}
void run()
{
tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this);
}
Grid<Real> &a;
const Grid<Real> &b;
bool keepMax;
};
template<class T> Grid<T> &Grid<T>::safeDivide(const Grid<T> &a)
{
knGridSafeDiv<T>(*this, a);
@@ -1069,18 +928,6 @@ void Grid<T>::permuteAxesCopyToGrid(int axis0, int axis1, int axis2, Grid<T> &ou
"Permuted grids must have the same dimensions!");
knPermuteAxes<T>(*this, out, axis0, axis1, axis2);
}
template<> void Grid<Vec3>::join(const Grid<Vec3> &a, bool keepMax)
{
knJoinVec(*this, a, keepMax);
}
template<> void Grid<int>::join(const Grid<int> &a, bool keepMax)
{
knJoinInt(*this, a, keepMax);
}
template<> void Grid<Real>::join(const Grid<Real> &a, bool keepMax)
{
knJoinReal(*this, a, keepMax);
}
template<> Real Grid<Real>::getMax() const
{

View File

@@ -966,38 +966,10 @@ template<class T> class Grid : public GridBase {
}
}
//! join other grid by either keeping min or max value at cell
void join(const Grid<T> &a, bool keepMax = true);
static PyObject *_W_27(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
Grid *pbo = dynamic_cast<Grid *>(Pb::objFromPy(_self));
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
pbPreparePlugin(pbo->getParent(), "Grid::join", !noTiming);
PyObject *_retval = 0;
{
ArgLocker _lock;
const Grid<T> &a = *_args.getPtr<Grid<T>>("a", 0, &_lock);
bool keepMax = _args.getOpt<bool>("keepMax", 1, true, &_lock);
pbo->_args.copy(_args);
_retval = getPyNone();
pbo->join(a, keepMax);
pbo->_args.check();
}
pbFinalizePlugin(pbo->getParent(), "Grid::join", !noTiming);
return _retval;
}
catch (std::exception &e) {
pbSetError("Grid::join", e.what());
return 0;
}
}
// common compound operators
//! get absolute max value in grid
Real getMaxAbs() const;
static PyObject *_W_28(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_27(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1022,7 +994,7 @@ template<class T> class Grid : public GridBase {
//! get max value in grid
Real getMax() const;
static PyObject *_W_29(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_28(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1047,7 +1019,7 @@ template<class T> class Grid : public GridBase {
//! get min value in grid
Real getMin() const;
static PyObject *_W_30(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_29(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1072,7 +1044,7 @@ template<class T> class Grid : public GridBase {
//! calculate L1 norm of grid content
Real getL1(int bnd = 0);
static PyObject *_W_31(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_30(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1098,7 +1070,7 @@ template<class T> class Grid : public GridBase {
//! calculate L2 norm of grid content
Real getL2(int bnd = 0);
static PyObject *_W_32(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_31(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1124,7 +1096,7 @@ template<class T> class Grid : public GridBase {
//! set all boundary cells to constant value (Dirichlet)
void setBound(T value, int boundaryWidth = 1);
static PyObject *_W_33(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_32(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1152,7 +1124,7 @@ template<class T> class Grid : public GridBase {
//! set all boundary cells to last inner value (Neumann)
void setBoundNeumann(int boundaryWidth = 1);
static PyObject *_W_34(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_33(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1179,7 +1151,7 @@ template<class T> class Grid : public GridBase {
//! get data pointer of grid
std::string getDataPointer();
static PyObject *_W_35(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_34(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1204,7 +1176,7 @@ template<class T> class Grid : public GridBase {
//! debugging helper, print grid from python. skip boundary of width bnd
void printGrid(int zSlice = -1, bool printIndex = false, int bnd = 1);
static PyObject *_W_36(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_35(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1272,7 +1244,7 @@ class MACGrid : public Grid<Vec3> {
{
mType = (GridType)(TypeMAC | TypeVec3);
}
static int _W_37(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static int _W_36(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
PbClass *obj = Pb::objFromPy(_self);
if (obj)
@@ -1354,7 +1326,7 @@ class MACGrid : public Grid<Vec3> {
//! set all boundary cells of a MAC grid to certain value (Dirchlet). Respects staggered grid
//! locations optionally, only set normal components
void setBoundMAC(Vec3 value, int boundaryWidth, bool normalOnly = false);
static PyObject *_W_38(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_37(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1395,7 +1367,7 @@ class FlagGrid : public Grid<int> {
{
mType = (GridType)(TypeFlags | TypeInt);
}
static int _W_39(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static int _W_38(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
PbClass *obj = Pb::objFromPy(_self);
if (obj)
@@ -1575,7 +1547,7 @@ class FlagGrid : public Grid<int> {
const std::string &inflow = " ",
const std::string &outflow = " ",
Grid<Real> *phiWalls = 0x00);
static PyObject *_W_40(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_39(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1609,7 +1581,7 @@ class FlagGrid : public Grid<int> {
//! set fluid flags inside levelset (liquids)
void updateFromLevelset(LevelsetGrid &levelset);
static PyObject *_W_41(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_40(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1636,7 +1608,7 @@ class FlagGrid : public Grid<int> {
//! set all cells (except obs/in/outflow) to type (fluid by default)
void fillGrid(int type = TypeFluid);
static PyObject *_W_42(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_41(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);
@@ -1665,7 +1637,7 @@ class FlagGrid : public Grid<int> {
//! warning for large grids! only regular int returned (due to python interface)
//! optionally creates mask in RealGrid (1 where flag matches, 0 otherwise)
int countCells(int flag, int bnd = 0, Grid<Real> *mask = NULL);
static PyObject *_W_43(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
static PyObject *_W_42(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
try {
PbArgs _args(_linargs, _kwds);

View File

@@ -8,11 +8,11 @@ namespace Manta {
#ifdef _C_FlagGrid
static const Pb::Register _R_26("FlagGrid", "FlagGrid", "Grid<int>");
template<> const char *Namify<FlagGrid>::S = "FlagGrid";
static const Pb::Register _R_27("FlagGrid", "FlagGrid", FlagGrid::_W_39);
static const Pb::Register _R_28("FlagGrid", "initDomain", FlagGrid::_W_40);
static const Pb::Register _R_29("FlagGrid", "updateFromLevelset", FlagGrid::_W_41);
static const Pb::Register _R_30("FlagGrid", "fillGrid", FlagGrid::_W_42);
static const Pb::Register _R_31("FlagGrid", "countCells", FlagGrid::_W_43);
static const Pb::Register _R_27("FlagGrid", "FlagGrid", FlagGrid::_W_38);
static const Pb::Register _R_28("FlagGrid", "initDomain", FlagGrid::_W_39);
static const Pb::Register _R_29("FlagGrid", "updateFromLevelset", FlagGrid::_W_40);
static const Pb::Register _R_30("FlagGrid", "fillGrid", FlagGrid::_W_41);
static const Pb::Register _R_31("FlagGrid", "countCells", FlagGrid::_W_42);
#endif
#ifdef _C_Grid
static const Pb::Register _R_32("Grid<int>", "Grid<int>", "GridBase");
@@ -35,95 +35,92 @@ static const Pb::Register _R_47("Grid<int>", "clamp", Grid<int>::_W_23);
static const Pb::Register _R_48("Grid<int>", "stomp", Grid<int>::_W_24);
static const Pb::Register _R_49("Grid<int>", "permuteAxes", Grid<int>::_W_25);
static const Pb::Register _R_50("Grid<int>", "permuteAxesCopyToGrid", Grid<int>::_W_26);
static const Pb::Register _R_51("Grid<int>", "join", Grid<int>::_W_27);
static const Pb::Register _R_52("Grid<int>", "getMaxAbs", Grid<int>::_W_28);
static const Pb::Register _R_53("Grid<int>", "getMax", Grid<int>::_W_29);
static const Pb::Register _R_54("Grid<int>", "getMin", Grid<int>::_W_30);
static const Pb::Register _R_55("Grid<int>", "getL1", Grid<int>::_W_31);
static const Pb::Register _R_56("Grid<int>", "getL2", Grid<int>::_W_32);
static const Pb::Register _R_57("Grid<int>", "setBound", Grid<int>::_W_33);
static const Pb::Register _R_58("Grid<int>", "setBoundNeumann", Grid<int>::_W_34);
static const Pb::Register _R_59("Grid<int>", "getDataPointer", Grid<int>::_W_35);
static const Pb::Register _R_60("Grid<int>", "printGrid", Grid<int>::_W_36);
static const Pb::Register _R_61("Grid<Real>", "Grid<Real>", "GridBase");
static const Pb::Register _R_51("Grid<int>", "getMaxAbs", Grid<int>::_W_27);
static const Pb::Register _R_52("Grid<int>", "getMax", Grid<int>::_W_28);
static const Pb::Register _R_53("Grid<int>", "getMin", Grid<int>::_W_29);
static const Pb::Register _R_54("Grid<int>", "getL1", Grid<int>::_W_30);
static const Pb::Register _R_55("Grid<int>", "getL2", Grid<int>::_W_31);
static const Pb::Register _R_56("Grid<int>", "setBound", Grid<int>::_W_32);
static const Pb::Register _R_57("Grid<int>", "setBoundNeumann", Grid<int>::_W_33);
static const Pb::Register _R_58("Grid<int>", "getDataPointer", Grid<int>::_W_34);
static const Pb::Register _R_59("Grid<int>", "printGrid", Grid<int>::_W_35);
static const Pb::Register _R_60("Grid<Real>", "Grid<Real>", "GridBase");
template<> const char *Namify<Grid<Real>>::S = "Grid<Real>";
static const Pb::Register _R_62("Grid<Real>", "Grid", Grid<Real>::_W_9);
static const Pb::Register _R_63("Grid<Real>", "save", Grid<Real>::_W_10);
static const Pb::Register _R_64("Grid<Real>", "load", Grid<Real>::_W_11);
static const Pb::Register _R_65("Grid<Real>", "clear", Grid<Real>::_W_12);
static const Pb::Register _R_66("Grid<Real>", "copyFrom", Grid<Real>::_W_13);
static const Pb::Register _R_67("Grid<Real>", "getGridType", Grid<Real>::_W_14);
static const Pb::Register _R_68("Grid<Real>", "add", Grid<Real>::_W_15);
static const Pb::Register _R_69("Grid<Real>", "sub", Grid<Real>::_W_16);
static const Pb::Register _R_70("Grid<Real>", "setConst", Grid<Real>::_W_17);
static const Pb::Register _R_71("Grid<Real>", "addConst", Grid<Real>::_W_18);
static const Pb::Register _R_72("Grid<Real>", "addScaled", Grid<Real>::_W_19);
static const Pb::Register _R_73("Grid<Real>", "mult", Grid<Real>::_W_20);
static const Pb::Register _R_74("Grid<Real>", "multConst", Grid<Real>::_W_21);
static const Pb::Register _R_75("Grid<Real>", "safeDivide", Grid<Real>::_W_22);
static const Pb::Register _R_76("Grid<Real>", "clamp", Grid<Real>::_W_23);
static const Pb::Register _R_77("Grid<Real>", "stomp", Grid<Real>::_W_24);
static const Pb::Register _R_78("Grid<Real>", "permuteAxes", Grid<Real>::_W_25);
static const Pb::Register _R_79("Grid<Real>", "permuteAxesCopyToGrid", Grid<Real>::_W_26);
static const Pb::Register _R_80("Grid<Real>", "join", Grid<Real>::_W_27);
static const Pb::Register _R_81("Grid<Real>", "getMaxAbs", Grid<Real>::_W_28);
static const Pb::Register _R_82("Grid<Real>", "getMax", Grid<Real>::_W_29);
static const Pb::Register _R_83("Grid<Real>", "getMin", Grid<Real>::_W_30);
static const Pb::Register _R_84("Grid<Real>", "getL1", Grid<Real>::_W_31);
static const Pb::Register _R_85("Grid<Real>", "getL2", Grid<Real>::_W_32);
static const Pb::Register _R_86("Grid<Real>", "setBound", Grid<Real>::_W_33);
static const Pb::Register _R_87("Grid<Real>", "setBoundNeumann", Grid<Real>::_W_34);
static const Pb::Register _R_88("Grid<Real>", "getDataPointer", Grid<Real>::_W_35);
static const Pb::Register _R_89("Grid<Real>", "printGrid", Grid<Real>::_W_36);
static const Pb::Register _R_90("Grid<Vec3>", "Grid<Vec3>", "GridBase");
static const Pb::Register _R_61("Grid<Real>", "Grid", Grid<Real>::_W_9);
static const Pb::Register _R_62("Grid<Real>", "save", Grid<Real>::_W_10);
static const Pb::Register _R_63("Grid<Real>", "load", Grid<Real>::_W_11);
static const Pb::Register _R_64("Grid<Real>", "clear", Grid<Real>::_W_12);
static const Pb::Register _R_65("Grid<Real>", "copyFrom", Grid<Real>::_W_13);
static const Pb::Register _R_66("Grid<Real>", "getGridType", Grid<Real>::_W_14);
static const Pb::Register _R_67("Grid<Real>", "add", Grid<Real>::_W_15);
static const Pb::Register _R_68("Grid<Real>", "sub", Grid<Real>::_W_16);
static const Pb::Register _R_69("Grid<Real>", "setConst", Grid<Real>::_W_17);
static const Pb::Register _R_70("Grid<Real>", "addConst", Grid<Real>::_W_18);
static const Pb::Register _R_71("Grid<Real>", "addScaled", Grid<Real>::_W_19);
static const Pb::Register _R_72("Grid<Real>", "mult", Grid<Real>::_W_20);
static const Pb::Register _R_73("Grid<Real>", "multConst", Grid<Real>::_W_21);
static const Pb::Register _R_74("Grid<Real>", "safeDivide", Grid<Real>::_W_22);
static const Pb::Register _R_75("Grid<Real>", "clamp", Grid<Real>::_W_23);
static const Pb::Register _R_76("Grid<Real>", "stomp", Grid<Real>::_W_24);
static const Pb::Register _R_77("Grid<Real>", "permuteAxes", Grid<Real>::_W_25);
static const Pb::Register _R_78("Grid<Real>", "permuteAxesCopyToGrid", Grid<Real>::_W_26);
static const Pb::Register _R_79("Grid<Real>", "getMaxAbs", Grid<Real>::_W_27);
static const Pb::Register _R_80("Grid<Real>", "getMax", Grid<Real>::_W_28);
static const Pb::Register _R_81("Grid<Real>", "getMin", Grid<Real>::_W_29);
static const Pb::Register _R_82("Grid<Real>", "getL1", Grid<Real>::_W_30);
static const Pb::Register _R_83("Grid<Real>", "getL2", Grid<Real>::_W_31);
static const Pb::Register _R_84("Grid<Real>", "setBound", Grid<Real>::_W_32);
static const Pb::Register _R_85("Grid<Real>", "setBoundNeumann", Grid<Real>::_W_33);
static const Pb::Register _R_86("Grid<Real>", "getDataPointer", Grid<Real>::_W_34);
static const Pb::Register _R_87("Grid<Real>", "printGrid", Grid<Real>::_W_35);
static const Pb::Register _R_88("Grid<Vec3>", "Grid<Vec3>", "GridBase");
template<> const char *Namify<Grid<Vec3>>::S = "Grid<Vec3>";
static const Pb::Register _R_91("Grid<Vec3>", "Grid", Grid<Vec3>::_W_9);
static const Pb::Register _R_92("Grid<Vec3>", "save", Grid<Vec3>::_W_10);
static const Pb::Register _R_93("Grid<Vec3>", "load", Grid<Vec3>::_W_11);
static const Pb::Register _R_94("Grid<Vec3>", "clear", Grid<Vec3>::_W_12);
static const Pb::Register _R_95("Grid<Vec3>", "copyFrom", Grid<Vec3>::_W_13);
static const Pb::Register _R_96("Grid<Vec3>", "getGridType", Grid<Vec3>::_W_14);
static const Pb::Register _R_97("Grid<Vec3>", "add", Grid<Vec3>::_W_15);
static const Pb::Register _R_98("Grid<Vec3>", "sub", Grid<Vec3>::_W_16);
static const Pb::Register _R_99("Grid<Vec3>", "setConst", Grid<Vec3>::_W_17);
static const Pb::Register _R_100("Grid<Vec3>", "addConst", Grid<Vec3>::_W_18);
static const Pb::Register _R_101("Grid<Vec3>", "addScaled", Grid<Vec3>::_W_19);
static const Pb::Register _R_102("Grid<Vec3>", "mult", Grid<Vec3>::_W_20);
static const Pb::Register _R_103("Grid<Vec3>", "multConst", Grid<Vec3>::_W_21);
static const Pb::Register _R_104("Grid<Vec3>", "safeDivide", Grid<Vec3>::_W_22);
static const Pb::Register _R_105("Grid<Vec3>", "clamp", Grid<Vec3>::_W_23);
static const Pb::Register _R_106("Grid<Vec3>", "stomp", Grid<Vec3>::_W_24);
static const Pb::Register _R_107("Grid<Vec3>", "permuteAxes", Grid<Vec3>::_W_25);
static const Pb::Register _R_108("Grid<Vec3>", "permuteAxesCopyToGrid", Grid<Vec3>::_W_26);
static const Pb::Register _R_109("Grid<Vec3>", "join", Grid<Vec3>::_W_27);
static const Pb::Register _R_110("Grid<Vec3>", "getMaxAbs", Grid<Vec3>::_W_28);
static const Pb::Register _R_111("Grid<Vec3>", "getMax", Grid<Vec3>::_W_29);
static const Pb::Register _R_112("Grid<Vec3>", "getMin", Grid<Vec3>::_W_30);
static const Pb::Register _R_113("Grid<Vec3>", "getL1", Grid<Vec3>::_W_31);
static const Pb::Register _R_114("Grid<Vec3>", "getL2", Grid<Vec3>::_W_32);
static const Pb::Register _R_115("Grid<Vec3>", "setBound", Grid<Vec3>::_W_33);
static const Pb::Register _R_116("Grid<Vec3>", "setBoundNeumann", Grid<Vec3>::_W_34);
static const Pb::Register _R_117("Grid<Vec3>", "getDataPointer", Grid<Vec3>::_W_35);
static const Pb::Register _R_118("Grid<Vec3>", "printGrid", Grid<Vec3>::_W_36);
static const Pb::Register _R_89("Grid<Vec3>", "Grid", Grid<Vec3>::_W_9);
static const Pb::Register _R_90("Grid<Vec3>", "save", Grid<Vec3>::_W_10);
static const Pb::Register _R_91("Grid<Vec3>", "load", Grid<Vec3>::_W_11);
static const Pb::Register _R_92("Grid<Vec3>", "clear", Grid<Vec3>::_W_12);
static const Pb::Register _R_93("Grid<Vec3>", "copyFrom", Grid<Vec3>::_W_13);
static const Pb::Register _R_94("Grid<Vec3>", "getGridType", Grid<Vec3>::_W_14);
static const Pb::Register _R_95("Grid<Vec3>", "add", Grid<Vec3>::_W_15);
static const Pb::Register _R_96("Grid<Vec3>", "sub", Grid<Vec3>::_W_16);
static const Pb::Register _R_97("Grid<Vec3>", "setConst", Grid<Vec3>::_W_17);
static const Pb::Register _R_98("Grid<Vec3>", "addConst", Grid<Vec3>::_W_18);
static const Pb::Register _R_99("Grid<Vec3>", "addScaled", Grid<Vec3>::_W_19);
static const Pb::Register _R_100("Grid<Vec3>", "mult", Grid<Vec3>::_W_20);
static const Pb::Register _R_101("Grid<Vec3>", "multConst", Grid<Vec3>::_W_21);
static const Pb::Register _R_102("Grid<Vec3>", "safeDivide", Grid<Vec3>::_W_22);
static const Pb::Register _R_103("Grid<Vec3>", "clamp", Grid<Vec3>::_W_23);
static const Pb::Register _R_104("Grid<Vec3>", "stomp", Grid<Vec3>::_W_24);
static const Pb::Register _R_105("Grid<Vec3>", "permuteAxes", Grid<Vec3>::_W_25);
static const Pb::Register _R_106("Grid<Vec3>", "permuteAxesCopyToGrid", Grid<Vec3>::_W_26);
static const Pb::Register _R_107("Grid<Vec3>", "getMaxAbs", Grid<Vec3>::_W_27);
static const Pb::Register _R_108("Grid<Vec3>", "getMax", Grid<Vec3>::_W_28);
static const Pb::Register _R_109("Grid<Vec3>", "getMin", Grid<Vec3>::_W_29);
static const Pb::Register _R_110("Grid<Vec3>", "getL1", Grid<Vec3>::_W_30);
static const Pb::Register _R_111("Grid<Vec3>", "getL2", Grid<Vec3>::_W_31);
static const Pb::Register _R_112("Grid<Vec3>", "setBound", Grid<Vec3>::_W_32);
static const Pb::Register _R_113("Grid<Vec3>", "setBoundNeumann", Grid<Vec3>::_W_33);
static const Pb::Register _R_114("Grid<Vec3>", "getDataPointer", Grid<Vec3>::_W_34);
static const Pb::Register _R_115("Grid<Vec3>", "printGrid", Grid<Vec3>::_W_35);
#endif
#ifdef _C_GridBase
static const Pb::Register _R_119("GridBase", "GridBase", "PbClass");
static const Pb::Register _R_116("GridBase", "GridBase", "PbClass");
template<> const char *Namify<GridBase>::S = "GridBase";
static const Pb::Register _R_120("GridBase", "GridBase", GridBase::_W_0);
static const Pb::Register _R_121("GridBase", "getSizeX", GridBase::_W_1);
static const Pb::Register _R_122("GridBase", "getSizeY", GridBase::_W_2);
static const Pb::Register _R_123("GridBase", "getSizeZ", GridBase::_W_3);
static const Pb::Register _R_124("GridBase", "getSize", GridBase::_W_4);
static const Pb::Register _R_125("GridBase", "is3D", GridBase::_W_5);
static const Pb::Register _R_126("GridBase", "is4D", GridBase::_W_6);
static const Pb::Register _R_127("GridBase", "getSizeT", GridBase::_W_7);
static const Pb::Register _R_128("GridBase", "getStrideT", GridBase::_W_8);
static const Pb::Register _R_117("GridBase", "GridBase", GridBase::_W_0);
static const Pb::Register _R_118("GridBase", "getSizeX", GridBase::_W_1);
static const Pb::Register _R_119("GridBase", "getSizeY", GridBase::_W_2);
static const Pb::Register _R_120("GridBase", "getSizeZ", GridBase::_W_3);
static const Pb::Register _R_121("GridBase", "getSize", GridBase::_W_4);
static const Pb::Register _R_122("GridBase", "is3D", GridBase::_W_5);
static const Pb::Register _R_123("GridBase", "is4D", GridBase::_W_6);
static const Pb::Register _R_124("GridBase", "getSizeT", GridBase::_W_7);
static const Pb::Register _R_125("GridBase", "getStrideT", GridBase::_W_8);
#endif
#ifdef _C_MACGrid
static const Pb::Register _R_129("MACGrid", "MACGrid", "Grid<Vec3>");
static const Pb::Register _R_126("MACGrid", "MACGrid", "Grid<Vec3>");
template<> const char *Namify<MACGrid>::S = "MACGrid";
static const Pb::Register _R_130("MACGrid", "MACGrid", MACGrid::_W_37);
static const Pb::Register _R_131("MACGrid", "setBoundMAC", MACGrid::_W_38);
static const Pb::Register _R_127("MACGrid", "MACGrid", MACGrid::_W_36);
static const Pb::Register _R_128("MACGrid", "setBoundMAC", MACGrid::_W_37);
#endif
static const Pb::Register _R_7("GridType_TypeNone", 0);
static const Pb::Register _R_8("GridType_TypeReal", 1);
@@ -250,9 +247,6 @@ void PbRegister_file_7()
KEEP_UNUSED(_R_126);
KEEP_UNUSED(_R_127);
KEEP_UNUSED(_R_128);
KEEP_UNUSED(_R_129);
KEEP_UNUSED(_R_130);
KEEP_UNUSED(_R_131);
}
}
} // namespace Manta

View File

@@ -525,7 +525,7 @@ struct knFlipSampleSecondaryParticlesMoreCylinders : public KernelBase {
if (!(flags(i, j, k) & itype))
return;
static RandomStream mRand(9832);
RandomStream mRand(9832);
Real radius =
0.25; // diameter=0.5 => sampling with two cylinders in each dimension since cell size=1
for (Real x = i - radius; x <= i + radius; x += 2 * radius) {
@@ -791,9 +791,11 @@ struct knFlipSampleSecondaryParticles : public KernelBase {
const int n = KE * (k_ta * TA + k_wc * WC) * dt; // number of secondary particles
if (n == 0)
return;
static RandomStream mRand(9832);
RandomStream mRand(9832);
Vec3 xi = Vec3(i, j, k) + mRand.getVec3(); // randomized offset uniform in cell
Vec3 xi = Vec3(i + mRand.getReal(),
j + mRand.getReal(),
k + mRand.getReal()); // randomized offset uniform in cell
Vec3 vi = v.getInterpolated(xi);
Vec3 dir = dt * vi; // direction of movement of current particle
Vec3 e1 = getNormalized(Vec3(dir.z, 0, -dir.x)); // perpendicular to dir
@@ -1832,7 +1834,7 @@ struct knFlipDeleteParticlesInObstacle : public KernelBase {
}
int gridIndex = flags.index(xidx);
// remove particles that penetrate obstacles
if (flags.isObstacle(gridIndex) || flags.isOutflow(gridIndex)) {
if (flags[gridIndex] == FlagGrid::TypeObstacle || flags[gridIndex] == FlagGrid::TypeOutflow) {
pts.kill(idx);
}
}

View File

@@ -37,8 +37,8 @@
#endif
#define WIN32_LEAN_AND_MEAN
#include <intrin.h>
#include <windows.h>
#include <intrin.h>
#if defined(__clang__)
# pragma GCC diagnostic push

View File

@@ -47,10 +47,10 @@
#ifndef __ATOMIC_OPS_UTILS_H__
#define __ATOMIC_OPS_UTILS_H__
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>

View File

@@ -25,8 +25,8 @@
#include "AUD_PyInit.h"
#include <AUD_Sound.h>
#include <python/PyAPI.h>
#include <python/PySound.h>
#include <python/PyAPI.h>
extern "C" {
extern void *BKE_sound_get_factory(void *sound);

View File

@@ -18,23 +18,23 @@
* \ingroup clog
*/
#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
/* Disable for small single threaded programs
* to avoid having to link with pthreads. */
#ifdef WITH_CLOG_PTHREADS
# include "atomic_ops.h"
# include <pthread.h>
# include "atomic_ops.h"
#endif
/* For 'isatty' to check for color. */
#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
# include <sys/time.h>
# include <unistd.h>
# include <sys/time.h>
#endif
#if defined(_MSC_VER)

View File

@@ -313,7 +313,9 @@ if(WITH_CYCLES_CUDA_BINARIES AND (NOT WITH_CYCLES_CUBIN_COMPILER))
set(MAX_MSVC 1910)
elseif(${CUDA_VERSION} EQUAL "9.1")
set(MAX_MSVC 1911)
elseif(${CUDA_VERSION} LESS "11.0")
elseif(${CUDA_VERSION} EQUAL "10.0")
set(MAX_MSVC 1999)
elseif(${CUDA_VERSION} EQUAL "10.1")
set(MAX_MSVC 1999)
endif()
if(NOT MSVC_VERSION LESS ${MAX_MSVC} OR CMAKE_C_COMPILER_ID MATCHES "Clang")
@@ -330,7 +332,7 @@ if(WITH_CYCLES_CUDA_BINARIES AND (NOT WITH_CYCLES_CUBIN_COMPILER))
endif()
# NVRTC gives wrong rendering result in CUDA 10.0, so we must use NVCC.
if(WITH_CYCLES_CUDA_BINARIES AND WITH_CYCLES_CUBIN_COMPILER AND NOT WITH_CYCLES_CUBIN_COMPILER_OVERRRIDE)
if(WITH_CYCLES_CUDA_BINARIES AND WITH_CYCLES_CUBIN_COMPILER)
if(NOT (${CUDA_VERSION} VERSION_LESS 10.0))
message(STATUS "cycles_cubin_cc not supported for CUDA 10.0+, using nvcc instead.")
set(WITH_CYCLES_CUBIN_COMPILER OFF)
@@ -348,6 +350,17 @@ if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
endif()
if(WITH_OPENCOLORIO)
add_definitions(-DWITH_OCIO)
include_directories(
SYSTEM
${OPENCOLORIO_INCLUDE_DIRS}
)
if(WIN32)
add_definitions(-DOpenColorIO_STATIC)
endif()
endif()
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
add_subdirectory(app)
endif()

View File

@@ -60,7 +60,6 @@ link_directories(
${TIFF_LIBPATH}
${OPENEXR_LIBPATH}
${OPENJPEG_LIBPATH}
${OPENVDB_LIBPATH}
)
if(WITH_OPENCOLORIO)

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdint.h>
#include <string>
#include <vector>
@@ -43,8 +43,7 @@ template<typename T> std::string to_string(const T &n)
class CompilationSettings {
public:
CompilationSettings()
: target_arch(0), bits(64), verbose(false), fast_math(false), ptx_only(false)
CompilationSettings() : target_arch(0), bits(64), verbose(false), fast_math(false)
{
}
@@ -58,13 +57,12 @@ class CompilationSettings {
int bits;
bool verbose;
bool fast_math;
bool ptx_only;
};
static bool compile_cuda(CompilationSettings &settings)
{
const char *headers[] = {"stdlib.h", "float.h", "math.h", "stdio.h", "stddef.h"};
const char *header_content[] = {"\n", "\n", "\n", "\n", "\n"};
const char *headers[] = {"stdlib.h", "float.h", "math.h", "stdio.h"};
const char *header_content[] = {"\n", "\n", "\n", "\n"};
printf("Building %s\n", settings.input_file.c_str());
@@ -85,8 +83,6 @@ static bool compile_cuda(CompilationSettings &settings)
options.push_back("-D__KERNEL_CUDA_VERSION__=" + std::to_string(cuewNvrtcVersion()));
options.push_back("-arch=compute_" + std::to_string(settings.target_arch));
options.push_back("--device-as-default-execution-space");
options.push_back("-DCYCLES_CUBIN_CC");
options.push_back("--std=c++11");
if (settings.fast_math)
options.push_back("--use_fast_math");
@@ -138,14 +134,10 @@ static bool compile_cuda(CompilationSettings &settings)
fprintf(stderr, "Error: nvrtcGetPTX failed (%d)\n\n", (int)result);
return false;
}
if (settings.ptx_only) {
settings.ptx_file = settings.output_file;
}
else {
/* Write a file in the temp folder with the ptx code. */
settings.ptx_file = OIIO::Filesystem::temp_directory_path() + "/" +
OIIO::Filesystem::unique_path();
}
/* Write a file in the temp folder with the ptx code. */
settings.ptx_file = OIIO::Filesystem::temp_directory_path() + "/" +
OIIO::Filesystem::unique_path();
FILE *f = fopen(settings.ptx_file.c_str(), "wb");
fwrite(&ptx_code[0], 1, ptx_size, f);
fclose(f);
@@ -257,9 +249,6 @@ static bool parse_parameters(int argc, const char **argv, CompilationSettings &s
"-D %L",
&settings.defines,
"Add additional defines",
"-ptx",
&settings.ptx_only,
"emit PTX code",
"-v",
&settings.verbose,
"Use verbose logging",
@@ -314,10 +303,8 @@ int main(int argc, const char **argv)
exit(EXIT_FAILURE);
}
if (!settings.ptx_only) {
if (!link_ptxas(settings)) {
exit(EXIT_FAILURE);
}
if (!link_ptxas(settings)) {
exit(EXIT_FAILURE);
}
return 0;

View File

@@ -20,11 +20,11 @@
#include "util/util_args.h"
#include "util/util_foreach.h"
#include "util/util_logging.h"
#include "util/util_path.h"
#include "util/util_stats.h"
#include "util/util_string.h"
#include "util/util_task.h"
#include "util/util_logging.h"
using namespace ccl;

View File

@@ -16,12 +16,12 @@
#include <stdio.h>
#include "device/device.h"
#include "render/buffers.h"
#include "render/camera.h"
#include "render/integrator.h"
#include "device/device.h"
#include "render/scene.h"
#include "render/session.h"
#include "render/integrator.h"
#include "util/util_args.h"
#include "util/util_foreach.h"

View File

@@ -16,9 +16,9 @@
#include <stdio.h>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <sstream>
#include "graph/node_xml.h"
@@ -32,8 +32,8 @@
#include "render/nodes.h"
#include "render/object.h"
#include "render/osl.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/scene.h"
#include "subd/subd_patch.h"
#include "subd/subd_split.h"

View File

@@ -92,20 +92,6 @@ if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()
if(WITH_NEW_OBJECT_TYPES)
add_definitions(-DWITH_NEW_OBJECT_TYPES)
endif()
if(WITH_OPENVDB)
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
list(APPEND INC_SYS
${OPENVDB_INCLUDE_DIRS}
)
list(APPEND LIB
${OPENVDB_LIBRARIES}
)
endif()
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# avoid link failure with clang 3.4 debug

View File

@@ -260,16 +260,15 @@ def list_render_passes(srl):
if crl.use_pass_volume_indirect: yield ("VolumeInd", "RGB", 'COLOR')
# Cryptomatte passes.
crypto_depth = (crl.pass_crypto_depth + 1) // 2
if crl.use_pass_crypto_object:
for i in range(0, crypto_depth):
yield ("CryptoObject" + '{:02d}'.format(i), "RGBA", 'COLOR')
for i in range(0, crl.pass_crypto_depth, 2):
yield ("CryptoObject" + '{:02d}'.format(i//2), "RGBA", 'COLOR')
if crl.use_pass_crypto_material:
for i in range(0, crypto_depth):
yield ("CryptoMaterial" + '{:02d}'.format(i), "RGBA", 'COLOR')
for i in range(0, crl.pass_crypto_depth, 2):
yield ("CryptoMaterial" + '{:02d}'.format(i//2), "RGBA", 'COLOR')
if srl.cycles.use_pass_crypto_asset:
for i in range(0, crypto_depth):
yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
for i in range(0, srl.cycles.pass_crypto_depth, 2):
yield ("CryptoAsset" + '{:02d}'.format(i//2), "RGBA", 'COLOR')
# Denoising passes.
if crl.use_denoising or crl.denoising_store_passes:

View File

@@ -444,20 +444,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=8,
)
volume_step_rate: FloatProperty(
name="Step Rate",
description="Globally adjust detail for volume rendering, on top of automatically estimated step size. "
"Higher values reduce render time, lower values render with more detail",
default=1.0,
min=0.01, max=100.0, soft_min=0.1, soft_max=10.0, precision=2
)
volume_preview_step_rate: FloatProperty(
name="Step Rate",
description="Globally adjust detail for volume rendering, on top of automatically estimated step size. "
"Higher values reduce render time, lower values render with more detail",
default=1.0,
min=0.01, max=100.0, soft_min=0.1, soft_max=10.0, precision=2
volume_step_size: FloatProperty(
name="Step Size",
description="Distance between volume shader samples when rendering the volume "
"(lower values give more accurate and detailed results, but also increased render time)",
default=0.1,
min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4,
unit='LENGTH'
)
volume_max_steps: IntProperty(
@@ -941,14 +934,6 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
default='LINEAR',
)
volume_step_rate: FloatProperty(
name="Step Rate",
description="Scale the distance between volume shader samples when rendering the volume "
"(lower values give more accurate and detailed results, but also increased render time)",
default=1.0,
min=0.001, max=1000.0, soft_min=0.1, soft_max=10.0, precision=4
)
displacement_method: EnumProperty(
name="Displacement Method",
description="Method to use for the displacement",
@@ -1059,13 +1044,6 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
items=enum_volume_interpolation,
default='LINEAR',
)
volume_step_size: FloatProperty(
name="Step Size",
description="Distance between volume shader samples when rendering the volume "
"(lower values give more accurate and detailed results, but also increased render time)",
default=1.0,
min=0.0000001, max=100000.0, soft_min=0.1, soft_max=100.0, precision=4
)
@classmethod
def register(cls):

View File

@@ -373,7 +373,7 @@ class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
col = layout.column()
sub = col.column(align=True)
sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
sub.prop(cscene, "preview_dicing_rate", text="Viewport")
sub.prop(cscene, "preview_dicing_rate", text="Preview")
col.separator()
@@ -428,11 +428,9 @@ class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
col = layout.column(align=True)
col.prop(cscene, "volume_step_rate", text="Step Rate Render")
col.prop(cscene, "volume_preview_step_rate", text="Viewport")
layout.prop(cscene, "volume_max_steps", text="Max Steps")
col = layout.column()
col.prop(cscene, "volume_step_size", text="Step Size")
col.prop(cscene, "volume_max_steps", text="Max Steps")
class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel):
@@ -1698,9 +1696,6 @@ class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
sub.prop(cworld, "volume_sampling", text="Sampling")
col.prop(cworld, "volume_interpolation", text="Interpolation")
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
sub = col.column()
sub.active = not cworld.homogeneous_volume
sub.prop(cworld, "volume_step_size")
class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel):
@@ -1832,9 +1827,6 @@ class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
sub.prop(cmat, "volume_sampling", text="Sampling")
col.prop(cmat, "volume_interpolation", text="Interpolation")
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
sub = col.column()
sub.active = not cmat.homogeneous_volume
sub.prop(cmat, "volume_step_rate")
def draw(self, context):
self.draw_shared(self, context, context.material)
@@ -1917,6 +1909,7 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
flow.prop(cbk, "use_pass_diffuse")
flow.prop(cbk, "use_pass_glossy")
flow.prop(cbk, "use_pass_transmission")
flow.prop(cbk, "use_pass_subsurface")
flow.prop(cbk, "use_pass_ambient_occlusion")
flow.prop(cbk, "use_pass_emit")
@@ -2086,7 +2079,7 @@ class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
col.prop(rd, "simplify_child_particles", text="Child Particles")
col.prop(cscene, "texture_limit", text="Texture Limit")
col.prop(cscene, "ao_bounces", text="AO Bounces")
col.prop(rd, "use_simplify_smoke_highres")
class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel):
bl_label = "Render"

View File

@@ -595,6 +595,40 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, in
/* texture coords still needed */
}
static void export_hair_motion_validate_attribute(Hair *hair,
int motion_step,
int num_motion_keys,
bool have_motion)
{
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
const int num_keys = hair->curve_keys.size();
if (num_motion_keys != num_keys || !have_motion) {
/* No motion or hair "topology" changed, remove attributes again. */
if (num_motion_keys != num_keys) {
VLOG(1) << "Hair topology changed, removing attribute.";
}
else {
VLOG(1) << "No motion, removing attribute.";
}
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if (motion_step > 0) {
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
/* Motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now. */
for (int step = 0; step < motion_step; step++) {
float4 *mP = attr_mP->data_float4() + step * num_keys;
for (int key = 0; key < num_keys; key++) {
mP[key] = float3_to_float4(hair->curve_keys[key]);
mP[key].w = hair->curve_radius[key];
}
}
}
}
static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData)
{
int num_keys = 0;
@@ -714,40 +748,6 @@ static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int cu
return lerp(mP, mP2, remainder);
}
static void export_hair_motion_validate_attribute(Hair *hair,
int motion_step,
int num_motion_keys,
bool have_motion)
{
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
const int num_keys = hair->curve_keys.size();
if (num_motion_keys != num_keys || !have_motion) {
/* No motion or hair "topology" changed, remove attributes again. */
if (num_motion_keys != num_keys) {
VLOG(1) << "Hair topology changed, removing attribute.";
}
else {
VLOG(1) << "No motion, removing attribute.";
}
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if (motion_step > 0) {
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
/* Motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now. */
for (int step = 0; step < motion_step; step++) {
float4 *mP = attr_mP->data_float4() + step * num_keys;
for (int key = 0; key < num_keys; key++) {
mP[key] = float3_to_float4(hair->curve_keys[key]);
mP[key].w = hair->curve_radius[key];
}
}
}
}
static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step)
{
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
@@ -817,7 +817,7 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
}
}
/* In case of new attribute, we verify if there really was any motion. */
/* in case of new attribute, we verify if there really was any motion */
if (new_attribute) {
export_hair_motion_validate_attribute(hair, motion_step, i, have_motion);
}
@@ -1154,194 +1154,6 @@ void BlenderSync::sync_particle_hair(
}
}
#ifdef WITH_NEW_OBJECT_TYPES
static float4 hair_point_as_float4(BL::HairPoint b_point)
{
float4 mP = float3_to_float4(get_float3(b_point.co()));
mP.w = b_point.radius();
return mP;
}
static float4 interpolate_hair_points(BL::Hair b_hair,
const int first_point_index,
const int num_points,
const float step)
{
const float curve_t = step * (num_points - 1);
const int point_a = clamp((int)curve_t, 0, num_points - 1);
const int point_b = min(point_a + 1, num_points - 1);
const float t = curve_t - (float)point_a;
return lerp(hair_point_as_float4(b_hair.points[first_point_index + point_a]),
hair_point_as_float4(b_hair.points[first_point_index + point_b]),
t);
}
static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
{
/* TODO: optimize so we can straight memcpy arrays from Blender? */
/* Add requested attributes. */
Attribute *attr_intercept = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
}
/* Reserve memory. */
const int num_keys = b_hair.points.length();
const int num_curves = b_hair.curves.length();
if (num_curves > 0) {
VLOG(1) << "Exporting curve segments for hair " << hair->name;
}
hair->reserve_curves(num_curves, num_keys);
/* Export curves and points. */
vector<float> points_length;
BL::Hair::curves_iterator b_curve_iter;
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
BL::HairCurve b_curve = *b_curve_iter;
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
float3 prev_co = make_float3(0.0f, 0.0f, 0.0f);
float length = 0.0f;
if (attr_intercept) {
points_length.clear();
points_length.reserve(num_points);
}
/* Position and radius. */
for (int i = 0; i < num_points; i++) {
BL::HairPoint b_point = b_hair.points[first_point_index + i];
const float3 co = get_float3(b_point.co());
const float radius = b_point.radius();
hair->add_curve_key(co, radius);
if (attr_intercept) {
if (i > 0) {
length += len(co - prev_co);
points_length.push_back(length);
}
prev_co = co;
}
}
/* Normalized 0..1 attribute along curve. */
if (attr_intercept) {
for (int i = 0; i < num_points; i++) {
attr_intercept->add((length == 0.0f) ? 0.0f : points_length[i] / length);
}
}
/* Random number per curve. */
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
}
/* Curve. */
const int shader_index = 0;
hair->add_curve(first_point_index, shader_index);
}
}
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
{
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
<< motion_step;
/* Find or add attribute. */
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
bool new_attribute = false;
if (!attr_mP) {
VLOG(1) << "Creating new motion vertex position attribute";
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
new_attribute = true;
}
/* Export motion keys. */
const int num_keys = hair->curve_keys.size();
float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
bool have_motion = false;
int num_motion_keys = 0;
int curve_index = 0;
BL::Hair::curves_iterator b_curve_iter;
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
BL::HairCurve b_curve = *b_curve_iter;
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
Hair::Curve curve = hair->get_curve(curve_index);
curve_index++;
if (num_points == curve.num_keys) {
/* Number of keys matches. */
for (int i = 0; i < num_points; i++) {
int point_index = first_point_index + i;
if (point_index < num_keys) {
mP[num_motion_keys] = hair_point_as_float4(b_hair.points[point_index]);
num_motion_keys++;
if (!have_motion) {
/* TODO: use epsilon for comparison? Was needed for particles due to
* transform, but ideally should not happen anymore. */
float4 curve_key = float3_to_float4(hair->curve_keys[i]);
curve_key.w = hair->curve_radius[i];
have_motion = !(mP[i] == curve_key);
}
}
}
}
else {
/* Number of keys has changed. Generate an interpolated version
* to preserve motion blur. */
const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
for (int i = 0; i < curve.num_keys; i++) {
const float step = i * step_size;
mP[num_motion_keys] = interpolate_hair_points(b_hair, first_point_index, num_points, step);
num_motion_keys++;
}
have_motion = true;
}
}
/* In case of new attribute, we verify if there really was any motion. */
if (new_attribute) {
export_hair_motion_validate_attribute(hair, motion_step, num_motion_keys, have_motion);
}
}
#endif /* WITH_NEW_OBJECT_TYPES */
/* Hair object. */
void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step)
{
#ifdef WITH_NEW_OBJECT_TYPES
/* Convert Blender hair to Cycles curves. */
BL::Hair b_hair(b_ob.data());
if (motion) {
export_hair_curves_motion(hair, b_hair, motion_step);
}
else {
export_hair_curves(scene, hair, b_hair);
}
#else
(void)hair;
(void)b_ob;
(void)motion;
(void)motion_step;
#endif /* WITH_NEW_OBJECT_TYPES */
}
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
BL::Object b_ob,
Geometry *geom,
@@ -1367,24 +1179,14 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
geom->used_shaders = used_shaders;
if (view_layer.use_hair && scene->curve_system_manager->use_curves) {
#ifdef WITH_NEW_OBJECT_TYPES
if (b_ob.type() == BL::Object::type_HAIR) {
/* Hair object. */
sync_hair(hair, b_ob, false);
assert(mesh == NULL);
}
else
#endif
{
/* Particle hair. */
bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
/* Particle hair. */
bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
if (b_mesh) {
sync_particle_hair(geom, b_mesh, b_ob, false);
free_object_to_mesh(b_data, b_ob, b_mesh);
}
if (b_mesh) {
sync_particle_hair(geom, b_mesh, b_ob, false);
free_object_to_mesh(b_data, b_ob, b_mesh);
}
}
@@ -1411,24 +1213,13 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
#ifdef WITH_NEW_OBJECT_TYPES
if (b_ob.type() == BL::Object::type_HAIR) {
/* Hair object. */
sync_hair(hair, b_ob, true, motion_step);
assert(mesh == NULL);
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
if (b_mesh) {
sync_particle_hair(geom, b_mesh, b_ob, true, motion_step);
free_object_to_mesh(b_data, b_ob, b_mesh);
return;
}
else
#endif
{
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
if (b_mesh) {
sync_particle_hair(geom, b_mesh, b_ob, true, motion_step);
free_object_to_mesh(b_data, b_ob, b_mesh);
return;
}
}
}
/* No deformation on this frame, copy coordinates if other frames did have it. */

View File

@@ -18,9 +18,9 @@
#define __BLENDER_DEVICE_H__
#include "MEM_guardedalloc.h"
#include "RNA_types.h"
#include "RNA_access.h"
#include "RNA_blender_cpp.h"
#include "RNA_types.h"
#include "device/device.h"

View File

@@ -38,19 +38,11 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
GeometryKey key(b_key_id.ptr.data, use_particle_hair);
BL::Material material_override = view_layer.material_override;
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
scene->default_surface;
#ifdef WITH_NEW_OBJECT_TYPES
Geometry::Type geom_type = ((b_ob.type() == BL::Object::type_HAIR || use_particle_hair) &&
Shader *default_shader = scene->default_surface;
Geometry::Type geom_type = (use_particle_hair &&
(scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
Geometry::HAIR :
Geometry::MESH;
#else
Geometry::Type geom_type = ((use_particle_hair) &&
(scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
Geometry::HAIR :
Geometry::MESH;
#endif
/* Find shader indices. */
vector<Shader *> used_shaders;
@@ -129,14 +121,10 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
geom->name = ustring(b_ob_data.name().c_str());
#ifdef WITH_NEW_OBJECT_TYPES
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
sync_hair(b_depsgraph, b_ob, geom, used_shaders);
}
else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
else if (object_fluid_gas_domain_find(b_ob)) {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_volume(b_ob, mesh, used_shaders);
}
@@ -173,14 +161,10 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
return;
}
#ifdef WITH_NEW_OBJECT_TYPES
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
sync_hair_motion(b_depsgraph, b_ob, geom, motion_step);
}
else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
else if (object_fluid_gas_domain_find(b_ob)) {
/* No volume motion blur support yet. */
}
else {

View File

@@ -14,25 +14,25 @@
* limitations under the License.
*/
#include "render/camera.h"
#include "render/colorspace.h"
#include "render/mesh.h"
#include "render/object.h"
#include "render/scene.h"
#include "render/camera.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_session.h"
#include "blender/blender_util.h"
#include "subd/subd_patch.h"
#include "subd/subd_split.h"
#include "util/util_algorithm.h"
#include "util/util_disjoint_set.h"
#include "util/util_foreach.h"
#include "util/util_hash.h"
#include "util/util_logging.h"
#include "util/util_math.h"
#include "util/util_disjoint_set.h"
#include "mikktspace.h"

View File

@@ -15,14 +15,14 @@
*/
#include "render/camera.h"
#include "render/graph.h"
#include "render/integrator.h"
#include "render/graph.h"
#include "render/light.h"
#include "render/mesh.h"
#include "render/nodes.h"
#include "render/object.h"
#include "render/particles.h"
#include "render/scene.h"
#include "render/nodes.h"
#include "render/particles.h"
#include "render/shader.h"
#include "blender/blender_object_cull.h"
@@ -67,20 +67,10 @@ bool BlenderSync::object_is_mesh(BL::Object &b_ob)
return false;
}
BL::Object::type_enum type = b_ob.type();
#ifdef WITH_NEW_OBJECT_TYPES
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR) {
#else
if (type == BL::Object::type_VOLUME) {
#endif
/* Will be exported attached to mesh. */
return true;
}
else if (type == BL::Object::type_CURVE) {
if (b_ob.type() == BL::Object::type_CURVE) {
/* Skip exporting curves without faces, overhead can be
* significant if there are many for path animation. */
BL::Curve b_curve(b_ob_data);
BL::Curve b_curve(b_ob.data());
return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());

View File

@@ -19,8 +19,8 @@
#include "blender/CCL_api.h"
#include "blender/blender_device.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_session.h"
#include "blender/blender_util.h"
#include "render/denoising.h"
@@ -38,8 +38,8 @@
#ifdef WITH_OSL
# include "render/osl.h"
# include <OSL/oslconfig.h>
# include <OSL/oslquery.h>
# include <OSL/oslconfig.h>
#endif
#ifdef WITH_OPENCL

View File

@@ -41,8 +41,8 @@
#include "util/util_progress.h"
#include "util/util_time.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_session.h"
#include "blender/blender_util.h"
CCL_NAMESPACE_BEGIN

View File

@@ -24,14 +24,14 @@
#include "render/shader.h"
#include "blender/blender_image.h"
#include "blender/blender_sync.h"
#include "blender/blender_texture.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
#include "util/util_debug.h"
#include "util/util_foreach.h"
#include "util/util_set.h"
#include "util/util_string.h"
#include "util/util_set.h"
#include "util/util_task.h"
CCL_NAMESPACE_BEGIN
@@ -1260,7 +1260,6 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
shader->volume_sampling_method = get_volume_sampling(cmat);
shader->volume_interpolation_method = get_volume_interpolation(cmat);
shader->volume_step_rate = get_float(cmat, "volume_step_rate");
shader->displacement_method = get_displacement_method(cmat);
shader->set_graph(graph);
@@ -1325,7 +1324,6 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
shader->volume_sampling_method = get_volume_sampling(cworld);
shader->volume_interpolation_method = get_volume_interpolation(cworld);
shader->volume_step_rate = get_float(cworld, "volume_step_size");
}
else if (new_viewport_parameters.use_scene_world && b_world) {
BackgroundNode *background = new BackgroundNode();

View File

@@ -16,7 +16,6 @@
#include "render/background.h"
#include "render/camera.h"
#include "render/curves.h"
#include "render/film.h"
#include "render/graph.h"
#include "render/integrator.h"
@@ -26,18 +25,19 @@
#include "render/object.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/curves.h"
#include "device/device.h"
#include "blender/blender_device.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_session.h"
#include "blender/blender_util.h"
#include "util/util_debug.h"
#include "util/util_foreach.h"
#include "util/util_hash.h"
#include "util/util_opengl.h"
#include "util/util_hash.h"
CCL_NAMESPACE_BEGIN
@@ -178,11 +178,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
world_recalc = true;
}
}
/* Volume */
else if (b_id.is_a(&RNA_Volume)) {
BL::Volume b_volume(b_id);
geometry_map.set_recalc(b_volume);
}
}
BlenderViewportParameters new_viewport_parameters(b_v3d);
@@ -262,8 +257,7 @@ void BlenderSync::sync_integrator()
integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
integrator->volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") :
get_float(cscene, "volume_step_rate");
integrator->volume_step_size = get_float(cscene, "volume_step_size");
integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
@@ -633,11 +627,11 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
* User facing parameter is the number of pairs. */
int crypto_depth = divide_up(min(16, get_int(crp, "pass_crypto_depth")), 2);
int crypto_depth = min(16, get_int(crp, "pass_crypto_depth")) / 2;
scene->film->cryptomatte_depth = crypto_depth;
scene->film->cryptomatte_passes = CRYPT_NONE;
if (get_boolean(crp, "use_pass_crypto_object")) {
for (int i = 0; i < crypto_depth; i++) {
for (int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
@@ -646,7 +640,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
CRYPT_OBJECT);
}
if (get_boolean(crp, "use_pass_crypto_material")) {
for (int i = 0; i < crypto_depth; i++) {
for (int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
@@ -655,7 +649,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
CRYPT_MATERIAL);
}
if (get_boolean(crp, "use_pass_crypto_asset")) {
for (int i = 0; i < crypto_depth; i++) {
for (int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());

View File

@@ -18,9 +18,9 @@
#define __BLENDER_SYNC_H__
#include "MEM_guardedalloc.h"
#include "RNA_types.h"
#include "RNA_access.h"
#include "RNA_blender_cpp.h"
#include "RNA_types.h"
#include "blender/blender_id_map.h"
#include "blender/blender_viewport.h"
@@ -157,7 +157,6 @@ class BlenderSync {
BL::Object b_ob,
Geometry *geom,
int motion_step);
void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0);
void sync_particle_hair(
Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0);
void sync_curve_settings();

View File

@@ -17,8 +17,8 @@
#ifndef __BLENDER_TEXTURE_H__
#define __BLENDER_TEXTURE_H__
#include "blender/blender_sync.h"
#include <stdlib.h>
#include "blender/blender_sync.h"
CCL_NAMESPACE_BEGIN

View File

@@ -18,9 +18,9 @@
#define __BLENDER_VIEWPORT_H__
#include "MEM_guardedalloc.h"
#include "RNA_types.h"
#include "RNA_access.h"
#include "RNA_blender_cpp.h"
#include "RNA_types.h"
#include "render/film.h"
#include "util/util_param.h"

View File

@@ -15,20 +15,12 @@
*/
#include "render/colorspace.h"
#include "render/image.h"
#include "render/image_vdb.h"
#include "render/mesh.h"
#include "render/object.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
#ifdef WITH_OPENVDB
# include <openvdb/openvdb.h>
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
struct VolumeGrid *grid);
#endif
CCL_NAMESPACE_BEGIN
/* TODO: verify this is not loading unnecessary attributes. */
@@ -76,15 +68,6 @@ class BlenderSmokeLoader : public ImageLoader {
metadata.height = resolution.y * amplify;
metadata.depth = resolution.z * amplify;
/* Create a matrix to transform from object space to mesh texture space.
* This does not work with deformations but that can probably only be done
* well with a volume grid mapping of coordinates. */
BL::Mesh b_mesh(b_ob.data());
float3 loc, size;
mesh_texture_space(b_mesh, loc, size);
metadata.transform_3d = transform_translate(-loc) * transform_scale(size);
metadata.use_transform_3d = true;
return true;
}
@@ -207,7 +190,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
continue;
}
mesh->volume_clipping = b_domain.clipping();
mesh->volume_isovalue = b_domain.clipping();
Attribute *attr = mesh->attributes.add(std);
@@ -217,125 +200,19 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
attr->data_voxel() = scene->image_manager->add_image(loader, params);
}
}
class BlenderVolumeLoader : public VDBImageLoader {
public:
BlenderVolumeLoader(BL::Volume b_volume, const string &grid_name)
: VDBImageLoader(grid_name),
b_volume(b_volume),
b_volume_grid(PointerRNA_NULL),
unload(false)
{
#ifdef WITH_OPENVDB
/* Find grid with matching name. */
BL::Volume::grids_iterator b_grid_iter;
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
if (b_grid_iter->name() == grid_name) {
b_volume_grid = *b_grid_iter;
}
}
#endif
}
/* Create a matrix to transform from object space to mesh texture space.
* This does not work with deformations but that can probably only be done
* well with a volume grid mapping of coordinates. */
if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
Transform *tfm = attr->data_transform();
bool load_metadata(ImageMetaData &metadata) override
{
if (!b_volume_grid) {
return false;
}
BL::Mesh b_mesh(b_ob.data());
float3 loc, size;
mesh_texture_space(b_mesh, loc, size);
unload = !b_volume_grid.is_loaded();
#ifdef WITH_OPENVDB
Volume *volume = (Volume *)b_volume.ptr.data;
VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
#endif
return VDBImageLoader::load_metadata(metadata);
}
bool load_pixels(const ImageMetaData &metadata,
void *pixels,
const size_t pixel_size,
const bool associate_alpha) override
{
if (!b_volume_grid) {
return false;
}
return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
}
bool equals(const ImageLoader &other) const override
{
/* TODO: detect multiple volume datablocks with the same filepath. */
const BlenderVolumeLoader &other_loader = (const BlenderVolumeLoader &)other;
return b_volume == other_loader.b_volume && b_volume_grid == other_loader.b_volume_grid;
}
void cleanup() override
{
VDBImageLoader::cleanup();
if (b_volume_grid && unload) {
b_volume_grid.unload();
}
}
BL::Volume b_volume;
BL::VolumeGrid b_volume_grid;
bool unload;
};
static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
{
BL::Volume b_volume(b_ob.data());
b_volume.grids.load(b_data.ptr.data);
BL::VolumeRender b_render(b_volume.render());
mesh->volume_clipping = b_render.clipping();
mesh->volume_step_size = b_render.step_size();
mesh->volume_object_space = (b_render.space() == BL::VolumeRender::space_OBJECT);
/* Find grid with matching name. */
BL::Volume::grids_iterator b_grid_iter;
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
BL::VolumeGrid b_grid = *b_grid_iter;
ustring name = ustring(b_grid.name());
AttributeStandard std = ATTR_STD_NONE;
if (name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
std = ATTR_STD_VOLUME_DENSITY;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
std = ATTR_STD_VOLUME_COLOR;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
std = ATTR_STD_VOLUME_FLAME;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
std = ATTR_STD_VOLUME_HEAT;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
std = ATTR_STD_VOLUME_TEMPERATURE;
}
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
std = ATTR_STD_VOLUME_VELOCITY;
}
if ((std != ATTR_STD_NONE && mesh->need_attribute(scene, std)) ||
mesh->need_attribute(scene, name)) {
Attribute *attr = (std != ATTR_STD_NONE) ?
mesh->attributes.add(std) :
mesh->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
ImageLoader *loader = new BlenderVolumeLoader(b_volume, name.string());
ImageParams params;
params.frame = b_volume.grids.frame();
attr->data_voxel() = scene->image_manager->add_image(loader, params);
}
*tfm = transform_translate(-loc) * transform_scale(size);
}
}
@@ -359,16 +236,9 @@ void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh, const vector<Shader
mesh->clear();
mesh->used_shaders = used_shaders;
/* Smoke domain. */
if (view_layer.use_volumes) {
if (b_ob.type() == BL::Object::type_VOLUME) {
/* Volume object. Create only attributes, bounding mesh will then
* be automatically generated later. */
sync_volume_object(b_data, b_ob, scene, mesh);
}
else {
/* Smoke domain. */
sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
}
sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
}
/* Tag update. */

View File

@@ -22,20 +22,20 @@
#include "bvh/bvh_params.h"
#include "bvh_split.h"
#include "render/curves.h"
#include "render/hair.h"
#include "render/mesh.h"
#include "render/object.h"
#include "render/scene.h"
#include "render/curves.h"
#include "util/util_algorithm.h"
#include "util/util_foreach.h"
#include "util/util_logging.h"
#include "util/util_progress.h"
#include "util/util_queue.h"
#include "util/util_simd.h"
#include "util/util_stack_allocator.h"
#include "util/util_simd.h"
#include "util/util_time.h"
#include "util/util_queue.h"
CCL_NAMESPACE_BEGIN

View File

@@ -35,9 +35,9 @@
#ifdef WITH_EMBREE
# include <embree3/rtcore_geometry.h>
# include <pmmintrin.h>
# include <xmmintrin.h>
# include <embree3/rtcore_geometry.h>
# include "bvh/bvh_embree.h"
@@ -45,9 +45,9 @@
*/
# include "kernel/bvh/bvh_embree.h"
# include "kernel/kernel_compat_cpu.h"
# include "kernel/split/kernel_split_data_types.h"
# include "kernel/kernel_globals.h"
# include "kernel/kernel_random.h"
# include "kernel/split/kernel_split_data_types.h"
# include "render/hair.h"
# include "render/mesh.h"

View File

@@ -18,8 +18,8 @@
#ifdef WITH_OPTIX
# include "bvh/bvh_optix.h"
# include "render/geometry.h"
# include "render/hair.h"
# include "render/geometry.h"
# include "render/mesh.h"
# include "render/object.h"
# include "util/util_foreach.h"

View File

@@ -39,8 +39,8 @@
# include "util/util_path.h"
# include "util/util_string.h"
# include "util/util_system.h"
# include "util/util_time.h"
# include "util/util_types.h"
# include "util/util_time.h"
# include "util/util_windows.h"
# include "kernel/split/kernel_split_data_types.h"

View File

@@ -25,11 +25,11 @@
#include "util/util_logging.h"
#include "util/util_math.h"
#include "util/util_opengl.h"
#include "util/util_string.h"
#include "util/util_system.h"
#include "util/util_time.h"
#include "util/util_system.h"
#include "util/util_types.h"
#include "util/util_vector.h"
#include "util/util_string.h"
CCL_NAMESPACE_BEGIN
@@ -597,7 +597,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
info.has_half_images = true;
info.has_volume_decoupled = true;
info.has_adaptive_stop_per_sample = true;
info.has_osl = true;
info.has_profiling = true;
@@ -640,7 +639,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
/* Accumulate device info. */
info.has_half_images &= device.has_half_images;
info.has_volume_decoupled &= device.has_volume_decoupled;
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
info.has_osl &= device.has_osl;
info.has_profiling &= device.has_profiling;
}

View File

@@ -27,8 +27,8 @@
#include "util/util_list.h"
#include "util/util_stats.h"
#include "util/util_string.h"
#include "util/util_texture.h"
#include "util/util_thread.h"
#include "util/util_texture.h"
#include "util/util_types.h"
#include "util/util_vector.h"
@@ -75,13 +75,12 @@ class DeviceInfo {
string description;
string id; /* used for user preferences, should stay fixed with changing hardware config */
int num;
bool display_device; /* GPU is used as a display device. */
bool has_half_images; /* Support half-float textures. */
bool has_volume_decoupled; /* Decoupled volume shading. */
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
bool has_osl; /* Support Open Shading Language. */
bool use_split_kernel; /* Use split or mega kernel. */
bool has_profiling; /* Supports runtime collection of profiling info. */
bool display_device; /* GPU is used as a display device. */
bool has_half_images; /* Support half-float textures. */
bool has_volume_decoupled; /* Decoupled volume shading. */
bool has_osl; /* Support Open Shading Language. */
bool use_split_kernel; /* Use split or mega kernel. */
bool has_profiling; /* Supports runtime collection of profiling info. */
int cpu_threads;
vector<DeviceInfo> multi_devices;
vector<DeviceInfo> denoising_devices;
@@ -95,7 +94,6 @@ class DeviceInfo {
display_device = false;
has_half_images = false;
has_volume_decoupled = false;
has_adaptive_stop_per_sample = false;
has_osl = false;
use_split_kernel = false;
has_profiling = false;

View File

@@ -839,7 +839,7 @@ class CPUDevice : public Device {
return true;
}
bool adaptive_sampling_filter(KernelGlobals *kg, RenderTile &tile, int sample)
bool adaptive_sampling_filter(KernelGlobals *kg, RenderTile &tile)
{
WorkTile wtile;
wtile.x = tile.x;
@@ -850,24 +850,11 @@ class CPUDevice : public Device {
wtile.stride = tile.stride;
wtile.buffer = (float *)tile.buffer;
/* For CPU we do adaptive stopping per sample so we can stop earlier, but
* for combined CPU + GPU rendering we match the GPU and do it per tile
* after a given number of sample steps. */
if (!kernel_data.integrator.adaptive_stop_per_sample) {
for (int y = wtile.y; y < wtile.y + wtile.h; ++y) {
for (int x = wtile.x; x < wtile.x + wtile.w; ++x) {
const int index = wtile.offset + x + y * wtile.stride;
float *buffer = wtile.buffer + index * kernel_data.film.pass_stride;
kernel_do_adaptive_stopping(kg, buffer, sample);
}
}
}
bool any = false;
for (int y = wtile.y; y < wtile.y + wtile.h; ++y) {
for (int y = tile.y; y < tile.y + tile.h; ++y) {
any |= kernel_do_adaptive_filter_x(kg, y, &wtile);
}
for (int x = wtile.x; x < wtile.x + wtile.w; ++x) {
for (int x = tile.x; x < tile.x + tile.w; ++x) {
any |= kernel_do_adaptive_filter_y(kg, x, &wtile);
}
return (!any);
@@ -930,7 +917,7 @@ class CPUDevice : public Device {
tile.sample = sample + 1;
if (task.adaptive_sampling.use && task.adaptive_sampling.need_filter(sample)) {
const bool stop = adaptive_sampling_filter(kg, tile, sample);
const bool stop = adaptive_sampling_filter(kg, tile);
if (stop) {
const int num_progress_samples = end_sample - sample;
tile.sample = end_sample;
@@ -1340,7 +1327,6 @@ void device_cpu_info(vector<DeviceInfo> &devices)
info.id = "CPU";
info.num = 0;
info.has_volume_decoupled = true;
info.has_adaptive_stop_per_sample = true;
info.has_osl = true;
info.has_half_images = true;
info.has_profiling = true;

View File

@@ -16,9 +16,9 @@
#ifdef WITH_CUDA
# include "device/cuda/device_cuda.h"
# include "device/device.h"
# include "device/device_intern.h"
# include "device/cuda/device_cuda.h"
# include "util/util_logging.h"
# include "util/util_string.h"
@@ -129,7 +129,6 @@ void device_cuda_info(vector<DeviceInfo> &devices)
info.has_half_images = (major >= 3);
info.has_volume_decoupled = false;
info.has_adaptive_stop_per_sample = false;
int pci_location[3] = {0, 0, 0};
cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include "device/device_memory.h"
#include "device/device.h"
#include "device/device_memory.h"
CCL_NAMESPACE_BEGIN

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include <sstream>
#include <stdlib.h>
#include <sstream>
#include "device/device.h"
#include "device/device_intern.h"

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
#include "device/device_network.h"
#include "device/device.h"
#include "device/device_intern.h"
#include "device/device_network.h"
#include "util/util_foreach.h"
#include "util/util_logging.h"
@@ -311,7 +311,6 @@ void device_network_info(vector<DeviceInfo> &devices)
/* todo: get this info from device */
info.has_volume_decoupled = false;
info.has_adaptive_stop_per_sample = false;
info.has_osl = false;
devices.push_back(info);

View File

@@ -19,19 +19,19 @@
#ifdef WITH_NETWORK
# include <boost/archive/binary_iarchive.hpp>
# include <boost/archive/binary_oarchive.hpp>
# include <boost/archive/text_iarchive.hpp>
# include <boost/archive/text_oarchive.hpp>
# include <boost/archive/binary_iarchive.hpp>
# include <boost/archive/binary_oarchive.hpp>
# include <boost/array.hpp>
# include <boost/asio.hpp>
# include <boost/bind.hpp>
# include <boost/serialization/vector.hpp>
# include <boost/thread.hpp>
# include <deque>
# include <iostream>
# include <sstream>
# include <deque>
# include "render/buffers.h"

View File

@@ -16,9 +16,9 @@
#ifdef WITH_OPENCL
# include "device/opencl/device_opencl.h"
# include "device/device.h"
# include "device/device_intern.h"
# include "device/opencl/device_opencl.h"
# include "util/util_foreach.h"
# include "util/util_logging.h"
@@ -119,7 +119,6 @@ void device_opencl_info(vector<DeviceInfo> &devices)
info.display_device = true;
info.use_split_kernel = true;
info.has_volume_decoupled = false;
info.has_adaptive_stop_per_sample = false;
info.id = id;
/* Check OpenCL extensions */

View File

@@ -17,28 +17,28 @@
#ifdef WITH_OPTIX
# include "bvh/bvh.h"
# include "device/cuda/device_cuda.h"
# include "device/device_denoising.h"
# include "device/device_intern.h"
# include "render/buffers.h"
# include "device/device_denoising.h"
# include "bvh/bvh.h"
# include "render/scene.h"
# include "render/hair.h"
# include "render/mesh.h"
# include "render/object.h"
# include "render/scene.h"
# include "util/util_debug.h"
# include "util/util_logging.h"
# include "render/buffers.h"
# include "util/util_md5.h"
# include "util/util_path.h"
# include "util/util_time.h"
# include "util/util_debug.h"
# include "util/util_logging.h"
# ifdef WITH_CUDA_DYNLOAD
# include <cuew.h>
// Do not use CUDA SDK headers when using CUEW
# define OPTIX_DONT_INCLUDE_CUDA
# endif
# include <optix_function_table_definition.h>
# include <optix_stubs.h>
# include <optix_function_table_definition.h>
// TODO(pmours): Disable this once drivers have native support
# define OPTIX_DENOISER_NO_PIXEL_STRIDE 1
@@ -1558,7 +1558,7 @@ void device_optix_info(vector<DeviceInfo> &devices)
}
// Only add devices with RTX support
if (rtcore_version == 0 && !getenv("CYCLES_OPTIX_TEST"))
if (rtcore_version == 0)
it = cuda_devices.erase(it);
else
++it;

View File

@@ -138,7 +138,8 @@ void DeviceTask::update_progress(RenderTile *rtile, int pixel_samples)
/* Adaptive Sampling */
AdaptiveSampling::AdaptiveSampling() : use(true), adaptive_step(0), min_samples(0)
AdaptiveSampling::AdaptiveSampling()
: use(true), adaptive_step(ADAPTIVE_SAMPLE_STEP), min_samples(0)
{
}

View File

@@ -88,12 +88,9 @@ class OpenCLInfo {
static bool device_supported(const string &platform_name, const cl_device_id device_id);
static bool platform_version_check(cl_platform_id platform, string *error = NULL);
static bool device_version_check(cl_device_id device, string *error = NULL);
static bool get_device_version(cl_device_id device,
int *r_major,
int *r_minor,
string *error = NULL);
static string get_hardware_id(const string &platform_name, cl_device_id device_id);
static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices);
static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices,
bool force_all = false);
/* ** Some handy shortcuts to low level cl*GetInfo() functions. ** */

View File

@@ -257,16 +257,16 @@ void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
/* Ordered with most complex kernels first, to reduce overall compile time. */
ADD_SPLIT_KERNEL_PROGRAM(subsurface_scatter);
ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
if (requested_features.use_volume || is_preview) {
ADD_SPLIT_KERNEL_PROGRAM(do_volume);
}
ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
ADD_SPLIT_KERNEL_PROGRAM(lamp_emission);
ADD_SPLIT_KERNEL_PROGRAM(holdout_emission_blurring_pathtermination_ao);
ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_dl);
ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_ao);
ADD_SPLIT_KERNEL_PROGRAM(holdout_emission_blurring_pathtermination_ao);
ADD_SPLIT_KERNEL_PROGRAM(lamp_emission);
ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
/* Quick kernels bundled in a single program to reduce overhead of starting
* Blender processes. */
@@ -1896,17 +1896,6 @@ string OpenCLDevice::kernel_build_options(const string *debug_src)
{
string build_options = "-cl-no-signed-zeros -cl-mad-enable ";
/* Build with OpenCL 2.0 if available, this improves performance
* with AMD OpenCL drivers on Windows and Linux (legacy drivers).
* Note that OpenCL selects the highest 1.x version by default,
* only for 2.0 do we need the explicit compiler flag. */
int version_major, version_minor;
if (OpenCLInfo::get_device_version(cdDevice, &version_major, &version_minor)) {
if (version_major >= 2) {
build_options += "-cl-std=CL2.0 ";
}
}
if (platform_name == "NVIDIA CUDA") {
build_options +=
"-D__KERNEL_OPENCL_NVIDIA__ "

View File

@@ -19,8 +19,8 @@
#include "device/device.h"
#include "util/util_map.h"
#include "util/util_string.h"
#include "util/util_vector.h"
#include "util/util_string.h"
#include "clew.h"

View File

@@ -16,16 +16,15 @@
#ifdef WITH_OPENCL
# include "device/device_intern.h"
# include "device/opencl/device_opencl.h"
# include "device/device_intern.h"
# include "util/util_debug.h"
# include "util/util_logging.h"
# include "util/util_md5.h"
# include "util/util_path.h"
# include "util/util_semaphore.h"
# include "util/util_system.h"
# include "util/util_time.h"
# include "util/util_system.h"
using std::cerr;
using std::endl;
@@ -391,27 +390,8 @@ static void escape_python_string(string &str)
string_replace(str, "'", "\'");
}
static int opencl_compile_process_limit()
{
/* Limit number of concurrent processes compiling, with a heuristic based
* on total physical RAM and estimate of memory usage needed when compiling
* with all Cycles features enabled.
*
* This is somewhat arbitrary as we don't know the actual available RAM or
* how much the kernel compilation will needed depending on the features, but
* better than not limiting at all. */
static const int64_t GB = 1024LL * 1024LL * 1024LL;
static const int64_t process_memory = 2 * GB;
static const int64_t base_memory = 2 * GB;
static const int64_t system_memory = system_physical_ram();
static const int64_t process_limit = (system_memory - base_memory) / process_memory;
return max((int)process_limit, 1);
}
bool OpenCLDevice::OpenCLProgram::compile_separate(const string &clbin)
{
/* Construct arguments. */
vector<string> args;
args.push_back("--background");
args.push_back("--factory-startup");
@@ -439,23 +419,14 @@ bool OpenCLDevice::OpenCLProgram::compile_separate(const string &clbin)
kernel_file_escaped.c_str(),
clbin_escaped.c_str()));
/* Limit number of concurrent processes compiling. */
static thread_counting_semaphore semaphore(opencl_compile_process_limit());
semaphore.acquire();
/* Compile. */
const double starttime = time_dt();
double starttime = time_dt();
add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false);
add_log(string("Build flags: ") + kernel_build_options, true);
const bool success = system_call_self(args);
const double elapsed = time_dt() - starttime;
semaphore.release();
if (!success || !path_exists(clbin)) {
if (!system_call_self(args) || !path_exists(clbin)) {
return false;
}
double elapsed = time_dt() - starttime;
add_log(
string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed),
false);
@@ -776,10 +747,6 @@ bool OpenCLInfo::device_supported(const string &platform_name, const cl_device_i
}
VLOG(3) << "OpenCL driver version " << driver_major << "." << driver_minor;
if (getenv("CYCLES_OPENCL_TEST")) {
return true;
}
/* It is possible to have Iris GPU on AMD/Apple OpenCL framework
* (aka, it will not be on Intel framework). This isn't supported
* and needs an explicit blacklist.
@@ -839,30 +806,18 @@ bool OpenCLInfo::platform_version_check(cl_platform_id platform, string *error)
return true;
}
bool OpenCLInfo::get_device_version(cl_device_id device, int *r_major, int *r_minor, string *error)
bool OpenCLInfo::device_version_check(cl_device_id device, string *error)
{
const int req_major = 1, req_minor = 1;
int major, minor;
char version[256];
clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, sizeof(version), &version, NULL);
if (sscanf(version, "OpenCL C %d.%d", r_major, r_minor) < 2) {
if (sscanf(version, "OpenCL C %d.%d", &major, &minor) < 2) {
if (error != NULL) {
*error = string_printf("OpenCL: failed to parse OpenCL C version string (%s).", version);
}
return false;
}
if (error != NULL) {
*error = "";
}
return true;
}
bool OpenCLInfo::device_version_check(cl_device_id device, string *error)
{
const int req_major = 1, req_minor = 1;
int major, minor;
if (!get_device_version(device, &major, &minor, error)) {
return false;
}
if (!((major == req_major && minor >= req_minor) || (major > req_major))) {
if (error != NULL) {
*error = string_printf("OpenCL: C version 1.1 or later required, found %d.%d", major, minor);
@@ -903,7 +858,7 @@ string OpenCLInfo::get_hardware_id(const string &platform_name, cl_device_id dev
return "";
}
void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices)
void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices, bool force_all)
{
const cl_device_type device_type = OpenCLInfo::device_type();
static bool first_time = true;
@@ -969,7 +924,7 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
FIRST_VLOG(2) << "Ignoring device " << device_name << " due to old compiler version.";
continue;
}
if (device_supported(platform_name, device_id)) {
if (force_all || device_supported(platform_name, device_id)) {
cl_device_type device_type;
if (!get_device_type(device_id, &device_type, &error)) {
FIRST_VLOG(2) << "Ignoring device " << device_name

View File

@@ -452,7 +452,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
endif()
add_custom_command(
OUTPUT ${cuda_file}
OUTPUT ${cuda_cubin}
COMMAND ${CUBIN_CC_ENV}
"$<TARGET_FILE:cycles_cubin_cc>"
-target ${CUDA_ARCH}
@@ -461,6 +461,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
-v
-cuda-toolkit-dir "${CUDA_TOOLKIT_ROOT_DIR}"
DEPENDS ${kernel_sources} cycles_cubin_cc)
set(cuda_file ${cuda_cubin})
else()
add_custom_command(
OUTPUT ${cuda_file}
@@ -516,6 +517,7 @@ if(WITH_CYCLES_DEVICE_OPTIX)
-I "${OPTIX_INCLUDE_DIR}"
-I "${CMAKE_CURRENT_SOURCE_DIR}/.."
-I "${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda"
-arch=sm_30
--use_fast_math
-o ${output})
@@ -523,62 +525,25 @@ if(WITH_CYCLES_DEVICE_OPTIX)
set(cuda_flags ${cuda_flags}
-D __KERNEL_DEBUG__)
endif()
if(WITH_CYCLES_CUBIN_COMPILER)
# Needed to find libnvrtc-builtins.so. Can't do it from inside
# cycles_cubin_cc since the env variable is read before main()
if(APPLE)
set(CUBIN_CC_ENV ${CMAKE_COMMAND}
-E env DYLD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib")
elseif(UNIX)
set(CUBIN_CC_ENV ${CMAKE_COMMAND}
-E env LD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib64")
endif()
add_custom_command(
OUTPUT
${output}
DEPENDS
${input}
${SRC_HEADERS}
${SRC_KERNELS_CUDA_HEADERS}
${SRC_KERNELS_OPTIX_HEADERS}
${SRC_BVH_HEADERS}
${SRC_SVM_HEADERS}
${SRC_GEOM_HEADERS}
${SRC_CLOSURE_HEADERS}
${SRC_UTIL_HEADERS}
COMMAND
${CUDA_NVCC_EXECUTABLE} --ptx ${cuda_flags} ${input}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}")
add_custom_command(
OUTPUT ${output}
DEPENDS
${input}
${SRC_HEADERS}
${SRC_KERNELS_CUDA_HEADERS}
${SRC_KERNELS_OPTIX_HEADERS}
${SRC_BVH_HEADERS}
${SRC_SVM_HEADERS}
${SRC_GEOM_HEADERS}
${SRC_CLOSURE_HEADERS}
${SRC_UTIL_HEADERS}
COMMAND ${CUBIN_CC_ENV}
"$<TARGET_FILE:cycles_cubin_cc>"
-target 30
-ptx
-i ${CMAKE_CURRENT_SOURCE_DIR}/${input}
${cuda_flags}
-v
-cuda-toolkit-dir "${CUDA_TOOLKIT_ROOT_DIR}"
DEPENDS ${kernel_sources} cycles_cubin_cc)
else()
add_custom_command(
OUTPUT
${output}
DEPENDS
${input}
${SRC_HEADERS}
${SRC_KERNELS_CUDA_HEADERS}
${SRC_KERNELS_OPTIX_HEADERS}
${SRC_BVH_HEADERS}
${SRC_SVM_HEADERS}
${SRC_GEOM_HEADERS}
${SRC_CLOSURE_HEADERS}
${SRC_UTIL_HEADERS}
COMMAND
${CUDA_NVCC_EXECUTABLE}
--ptx
-arch=sm_30
${cuda_flags}
${input}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}")
endif()
list(APPEND optix_ptx ${output})
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${output}" ${CYCLES_INSTALL_PATH}/lib)

View File

@@ -493,36 +493,6 @@ ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
}
/* Hair Albedo */
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
const float azimuthal_roughness)
{
const float x = azimuthal_roughness;
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
}
ccl_device float3 bsdf_principled_hair_albedo(ShaderClosure *sc)
{
PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
return exp3(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
}
ccl_device_inline float3
bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness)
{
const float3 sigma = log3(color) /
bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
return sigma * sigma;
}
ccl_device_inline float3 bsdf_principled_hair_sigma_from_concentration(const float eumelanin,
const float pheomelanin)
{
return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
}
CCL_NAMESPACE_END
#endif /* __BSDF_HAIR_PRINCIPLED_H__ */

View File

@@ -103,21 +103,17 @@ ccl_device_inline
const Ray *ray,
float3 verts[3])
{
# ifdef __KERNEL_OPTIX__
/* isect->t is always in world space with OptiX. */
return motion_triangle_refine(kg, sd, isect, ray, verts);
# else
float3 P = ray->P;
float3 D = ray->D;
float t = isect->t;
# ifdef __INTERSECTION_REFINE__
# ifdef __INTERSECTION_REFINE__
if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
# ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
# else
# else
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
# endif
# endif
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D);
@@ -139,20 +135,19 @@ ccl_device_inline
P = P + D * rt;
if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
# ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_tfm;
# else
# else
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
# endif
# endif
P = transform_point(&tfm, P);
}
return P;
# else /* __INTERSECTION_REFINE__ */
# else /* __INTERSECTION_REFINE__ */
return P + D * t;
# endif /* __INTERSECTION_REFINE__ */
# endif
# endif /* __INTERSECTION_REFINE__ */
}
#endif /* __BVH_LOCAL__ */

View File

@@ -320,26 +320,6 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
return kernel_tex_fetch(__objects, object).patch_map_offset;
}
/* Volume step size */
ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
{
if (object == OBJECT_NONE) {
return 1.0f;
}
return kernel_tex_fetch(__objects, object).surface_area;
}
ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
{
if (object == OBJECT_NONE) {
return kernel_data.background.volume_step_size;
}
return kernel_tex_fetch(__object_volume_step, object);
}
/* Pass ID for shader */
ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)

View File

@@ -690,20 +690,16 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
const Intersection *isect,
const Ray *ray)
{
#ifdef __KERNEL_OPTIX__
/* isect->t is always in world space with OptiX. */
return triangle_refine(kg, sd, isect, ray);
#else
float3 P = ray->P;
float3 D = ray->D;
float t = isect->t;
if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
# else
#else
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
# endif
#endif
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D);
@@ -712,7 +708,7 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
P = P + D * t;
# ifdef __INTERSECTION_REFINE__
#ifdef __INTERSECTION_REFINE__
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0),
tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1),
@@ -732,20 +728,19 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
float rt = dot(edge2, qvec) / det;
P = P + D * rt;
}
# endif /* __INTERSECTION_REFINE__ */
#endif /* __INTERSECTION_REFINE__ */
if (isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_tfm;
# else
#else
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
# endif
#endif
P = transform_point(&tfm, P);
}
return P;
#endif
}
CCL_NAMESPACE_END

View File

@@ -51,14 +51,10 @@ ccl_device float volume_attribute_float(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
/* todo: optimize this so we don't have to transform both here and in
* kernel_tex_image_interp_3d when possible. Also could optimize for the
* common case where transform is translation/scale only. */
float3 P = sd->P;
object_inverse_position_transform(kg, sd, &P);
float3 P = volume_normalized_position(kg, sd, sd->P);
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
INTERPOLATION_NONE;
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
return average(float4_to_float3(r));
}
@@ -66,11 +62,10 @@ ccl_device float3 volume_attribute_float3(KernelGlobals *kg,
const ShaderData *sd,
const AttributeDescriptor desc)
{
float3 P = sd->P;
object_inverse_position_transform(kg, sd, &P);
float3 P = volume_normalized_position(kg, sd, sd->P);
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
INTERPOLATION_NONE;
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
if (r.w > 1e-6f && r.w != 1.0f) {
/* For RGBA colors, unpremultiply after interpolation. */

View File

@@ -19,8 +19,8 @@
/* CPU Kernel Interface */
#include "kernel/kernel_types.h"
#include "util/util_types.h"
#include "kernel/kernel_types.h"
CCL_NAMESPACE_BEGIN

View File

@@ -150,7 +150,6 @@ ccl_device void kernel_adaptive_post_adjust(KernelGlobals *kg,
}
#endif /* __DENOISING_FEATURES__ */
/* Cryptomatte. */
if (kernel_data.film.cryptomatte_passes) {
int num_slots = 0;
num_slots += (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) ? 1 : 0;
@@ -163,14 +162,6 @@ ccl_device void kernel_adaptive_post_adjust(KernelGlobals *kg,
id_buffer[slot].y *= sample_multiplier;
}
}
/* AOVs. */
for (int i = 0; i < kernel_data.film.pass_aov_value_num; i++) {
*(buffer + kernel_data.film.pass_aov_value + i) *= sample_multiplier;
}
for (int i = 0; i < kernel_data.film.pass_aov_color_num; i++) {
*((ccl_global float4 *)(buffer + kernel_data.film.pass_aov_color) + i) *= sample_multiplier;
}
}
/* This is a simple box filter in two passes.

View File

@@ -35,11 +35,11 @@
# define __NODES_FEATURES__ NODE_FEATURE_ALL
#endif
#include "util/util_half.h"
#include "util/util_math.h"
#include "util/util_simd.h"
#include "util/util_texture.h"
#include "util/util_half.h"
#include "util/util_types.h"
#include "util/util_texture.h"
#define ccl_addr_space

View File

@@ -37,11 +37,8 @@ typedef unsigned long long uint64_t;
typedef unsigned short half;
typedef unsigned long long CUtexObject;
#ifdef CYCLES_CUBIN_CC
# define FLT_MIN 1.175494350822287507969e-38f
# define FLT_MAX 340282346638528859811704183484516925440.0f
# define FLT_EPSILON 1.192092896e-07F
#endif
#define FLT_MIN 1.175494350822287507969e-38f
#define FLT_MAX 340282346638528859811704183484516925440.0f
__device__ half __float2half(const float f)
{

View File

@@ -35,11 +35,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned short half;
typedef unsigned long long CUtexObject;
#ifdef CYCLES_CUBIN_CC
# define FLT_MIN 1.175494350822287507969e-38f
# define FLT_MAX 340282346638528859811704183484516925440.0f
# define FLT_EPSILON 1.192092896e-07F
#endif
#define FLT_MIN 1.175494350822287507969e-38f
#define FLT_MAX 340282346638528859811704183484516925440.0f
__device__ half __float2half(const float f)
{

View File

@@ -22,8 +22,8 @@
#include "kernel/kernel_profiling.h"
#ifdef __KERNEL_CPU__
# include "util/util_map.h"
# include "util/util_vector.h"
# include "util/util_map.h"
#endif
#ifdef __KERNEL_OPENCL__

View File

@@ -87,9 +87,6 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)sc;
closure_albedo *= bsdf->avg_value;
}
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
closure_albedo *= bsdf_principled_hair_albedo(sc);
}
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
diffuse_albedo += closure_albedo;
@@ -403,13 +400,9 @@ ccl_device_inline void kernel_write_result(KernelGlobals *kg,
make_float4(L_sum.x * 2.0f, L_sum.y * 2.0f, L_sum.z * 2.0f, 0.0f));
}
#ifdef __KERNEL_CPU__
if ((sample > kernel_data.integrator.adaptive_min_samples) &&
kernel_data.integrator.adaptive_stop_per_sample) {
const int step = kernel_data.integrator.adaptive_step;
if ((sample & (step - 1)) == (step - 1)) {
kernel_do_adaptive_stopping(kg, buffer, sample);
}
if (sample > kernel_data.integrator.adaptive_min_samples &&
(sample & (ADAPTIVE_SAMPLE_STEP - 1)) == (ADAPTIVE_SAMPLE_STEP - 1)) {
kernel_do_adaptive_stopping(kg, buffer, sample);
}
#endif
}

View File

@@ -171,19 +171,19 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
Ray volume_ray = *ray;
volume_ray.t = (hit) ? isect->t : FLT_MAX;
float step_size = volume_stack_step_size(kg, state->volume_stack);
bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
# ifdef __VOLUME_DECOUPLED__
int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
bool decoupled = kernel_volume_use_decoupled(kg, step_size, direct, sampling_method);
bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
if (decoupled) {
/* cache steps along volume for repeated sampling */
VolumeSegment volume_segment;
shader_setup_from_volume(kg, sd, &volume_ray);
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
volume_segment.sampling_method = sampling_method;
@@ -229,7 +229,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
{
/* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate(
kg, state, sd, &volume_ray, L, throughput, step_size);
kg, state, sd, &volume_ray, L, throughput, heterogeneous);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {

View File

@@ -91,7 +91,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
Ray volume_ray = *ray;
volume_ray.t = (hit) ? isect->t : FLT_MAX;
float step_size = volume_stack_step_size(kg, state->volume_stack);
bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
# ifdef __VOLUME_DECOUPLED__
/* decoupled ray marching only supported on CPU */
@@ -100,7 +100,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
VolumeSegment volume_segment;
shader_setup_from_volume(kg, sd, &volume_ray);
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
/* direct light sampling */
if (volume_segment.closure_flag & SD_SCATTER) {
@@ -171,7 +171,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
path_state_branch(&ps, j, num_samples);
VolumeIntegrateResult result = kernel_volume_integrate(
kg, &ps, sd, &volume_ray, L, &tp, step_size);
kg, &ps, sd, &volume_ray, L, &tp, heterogeneous);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {

View File

@@ -428,17 +428,12 @@ ccl_device_noinline
hit = (ss_isect->num_hits > 0);
if (hit) {
#ifdef __KERNEL_OPTIX__
/* t is always in world space with OptiX. */
t = ss_isect->hits[0].t;
#else
/* Compute world space distance to surface hit. */
float3 D = ray->D;
object_inverse_dir_transform(kg, sd, &D);
D = normalize(D) * ss_isect->hits[0].t;
object_dir_transform(kg, sd, &D);
t = len(D);
#endif
}
/* Advance to new scatter location. */

View File

@@ -35,7 +35,6 @@ KERNEL_TEX(KernelObject, __objects)
KERNEL_TEX(Transform, __object_motion_pass)
KERNEL_TEX(DecomposedTransform, __object_motion)
KERNEL_TEX(uint, __object_flag)
KERNEL_TEX(float, __object_volume_step)
/* cameras */
KERNEL_TEX(DecomposedTransform, __camera_motion)

View File

@@ -63,6 +63,11 @@ CCL_NAMESPACE_BEGIN
#define VOLUME_STACK_SIZE 32
/* Adaptive sampling constants */
#define ADAPTIVE_SAMPLE_STEP 4
static_assert((ADAPTIVE_SAMPLE_STEP & (ADAPTIVE_SAMPLE_STEP - 1)) == 0,
"ADAPTIVE_SAMPLE_STEP must be power of two for bitwise operations to work");
/* Split kernel constants */
#define WORK_POOL_SIZE_GPU 64
#define WORK_POOL_SIZE_CPU 1
@@ -106,6 +111,8 @@ CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_AO_PREVIEW__
# define __SVM__
# define __EMISSION__
# define __TEXTURES__
# define __EXTRA_NODES__
# define __HOLDOUT__
# define __MULTI_CLOSURE__
# define __TRANSPARENT_SHADOWS__
@@ -880,13 +887,13 @@ enum ShaderDataFlag {
SD_HAS_DISPLACEMENT = (1 << 26),
/* Has constant emission (value stored in __shaders) */
SD_HAS_CONSTANT_EMISSION = (1 << 27),
/* Needs to access attributes for volume rendering */
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
/* Needs to access attributes */
SD_NEED_ATTRIBUTES = (1 << 28),
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
SD_VOLUME_MIS | SD_VOLUME_CUBIC | SD_HAS_BUMP | SD_HAS_DISPLACEMENT |
SD_HAS_CONSTANT_EMISSION | SD_NEED_VOLUME_ATTRIBUTES)
SD_HAS_CONSTANT_EMISSION | SD_NEED_ATTRIBUTES)
};
/* Object flags. */
@@ -1237,9 +1244,7 @@ typedef struct KernelFilm {
int pass_aov_color;
int pass_aov_value;
int pass_aov_color_num;
int pass_aov_value_num;
int pad1, pad2, pad3;
int pad1;
/* XYZ to rendering color space transform. float4 instead of float3 to
* ensure consistent padding/alignment across devices. */
@@ -1262,7 +1267,7 @@ typedef struct KernelFilm {
int use_display_exposure;
int use_display_pass_alpha;
int pad4, pad5, pad6;
int pad3, pad4, pad5;
} KernelFilm;
static_assert_align(KernelFilm, 16);
@@ -1270,7 +1275,6 @@ typedef struct KernelBackground {
/* only shader index */
int surface_shader;
int volume_shader;
float volume_step_size;
int transparent;
float transparent_roughness_squared_threshold;
@@ -1278,6 +1282,7 @@ typedef struct KernelBackground {
float ao_factor;
float ao_distance;
float ao_bounces_factor;
float ao_pad;
} KernelBackground;
static_assert_align(KernelBackground, 16);
@@ -1345,21 +1350,19 @@ typedef struct KernelIntegrator {
int sampling_pattern;
int aa_samples;
int adaptive_min_samples;
int adaptive_step;
int adaptive_stop_per_sample;
float adaptive_threshold;
/* volume render */
int use_volumes;
int volume_max_steps;
float volume_step_rate;
float volume_step_size;
int volume_samples;
int start_sample;
int max_closures;
int pad1;
int pad1, pad2, pad3;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);

Some files were not shown because too many files have changed in this diff Show More