Compare commits

...

139 commits

Author SHA1 Message Date
Lubosz Sarnecki
1ceeb39306 ports: Add openxr-loader.
Copy from vcpkg repository.
Add OpenXR to hifi-client-deps.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
80c7b8f993 OpenXrContext: Add Windows platform and bindings. (Untested) 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
7b1bbb6b2d OpenXrInputPlugin: Improve haptic feedback mapping. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
a2a1fca274 OpenXrInputPlugin: Fix hand orientation.
Use same orientation as OpenVR plugin.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
5ea07c8eb2 controllers: Improve openxr_index.json mapping. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
3be716cb05 OpenXrInputPlugin: Use left primary / secondary instead of face button names. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
cc20c37e05 controllers: openxr: Use actions for walking.
This makes the Y thumbstick axis work.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
e38f8bea34 OpenXrDisplayPlugin: Head pose is fixed now, update comment, refactor. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
3ca1d5f14b OpenXrDisplayPlugin: Run frame cycle on both threads.
Add synchronization.
Move xrWaitFrame and xrBeginFrame into beginFrameRender.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
ae5c1d8d00 OpenGlDisplayPlugin: Add possibility to present frames only once.
Don't present frame more than once in OpenXrDisplayPlugin.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
479b1aa6da OpenXrDisplayPlugin: Write layer poses as early as possible. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
385b33f6d2 OpenXrDisplayPlugin: Move swapchain aquire to hmdPresent. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
dfe92064b9 context: Improve errors when runtime is not available. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
e1f2551e30 OpenXrInput: comment debug output. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
7f4a489945 OpenXrInput: Map more Index controller.
* Add thumbstick click and touch.

* Add face and trigger touch.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
5cf56caf81 OpenXrInput: Rotate head and refactor sensor to avatar calculation. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
e98f08fa61 Application: Improve scoping. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
2e85e2e544 Application: Maintain orientation of eye offset matrix. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
c39868e8f0 Context: Maintain orientation of eye offset matrix. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
7ae59eb5dc OpenXrDisplayPlugin: Use view space eye positions.
Use view orientation for eye offset.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
86a71b589b plugins: Add OpenXR plugin.
Add OpenXrDisplayPlugin and OpenXrInputPlugin.
Add controller bindings for the Valve Index controller.
2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
45616a0db7 HmdDisplayPlugin: Fix whitespace. 2024-05-25 13:20:34 +02:00
Lubosz Sarnecki
521d9d278f UserInputMapper: Make error an error. 2024-05-25 13:20:33 +02:00
Lubosz Sarnecki
ca083aee9f Camera: Init default values. 2024-05-25 13:20:33 +02:00
Lubosz Sarnecki
c3595dc672 ports: Add jsoncpp.
The build demands it but it's missing.
Copy from upstream vcpkg repo.

Fixes the following error:
```
Computing installation plan...
error: while looking for jsoncpp:x64-linux:
overte-files/vcpkg/cfe0a2a0/ports/jsoncpp: error: jsoncpp does not exist
```
2024-05-25 13:20:33 +02:00
09e5a60c8b
Merge pull request #959 from overte-org/fix/avatar_recording
Fixed deadlocks in Recording API
2024-05-24 02:04:29 +02:00
8badda8128 Restored some blocking invoke calls in Recording API 2024-05-24 00:32:13 +02:00
ec5aa9ff1d
Merge pull request #966 from JulianGro/ubuntu_2404
Add Ubuntu 24.04 to server packaging
2024-05-23 21:58:46 +02:00
7bd436dd0d
Merge pull request #964 from overte-org/fix/script_window_crash
Fixed script signal proxy crashes
2024-05-23 21:26:43 +02:00
13a7ea356a
Merge pull request #978 from overte-org/fix/gltf_locale
Fixed locale problems with cgltf.h
2024-05-23 20:53:37 +02:00
bb8bac43ea
Merge pull request #960 from Armored-Dragon/SimplifiedUI-Fixes
SimplifiedUI adjustemnts
2024-05-23 02:14:59 +02:00
1ba6026a85 Added error message to float parser 2024-05-22 22:16:22 +02:00
4b9ddbc260 Fixed locale problems with cgltf.h 2024-05-22 02:50:28 +02:00
32fe7777e6 Disable broken Fedora 39 building 2024-05-20 13:08:04 +02:00
57864178c0 Remove blocking invoke calls from Recording API 2024-05-20 00:00:32 +02:00
9ec0842dab Add Ubuntu 24.04 to server package build workflow. 2024-05-19 14:47:13 +02:00
7080067afc Update nodejs to support Python3.12 2024-05-19 14:34:49 +02:00
a18aee1c60 Add Dockerfile_build_ubuntu-24.04 2024-05-19 14:12:12 +02:00
4e81908156 Fixed script signal proxy crashes 2024-05-19 01:48:18 +02:00
Armored Dragon
c541b64f66
I know the date...
Signed-off-by: Armored Dragon <publicmail@armoreddragon.com>
2024-05-16 16:35:55 -05:00
Armored Dragon
dd01944bbf
Fixed Settings UI in simplifiedUi.
Keepmenus by default.
Update HiFi links to Overte.

Signed-off-by: Armored Dragon <publicmail@armoreddragon.com>
2024-05-16 16:31:59 -05:00
8661e8a858
Merge pull request #955 from overte-org/fix/script_avatar_url_getter
Fix access check in getSkeletonModelURLFromScript
2024-05-16 01:40:15 +02:00
fe6d76b935 Fixed deadlocks in Recording API 2024-05-16 01:09:57 +02:00
9bdfc8344a Fix AvatarData::getSkeletonModelURLFromScript 2024-05-10 22:14:38 +02:00
Dale Glass
f9ffccfe00
Merge pull request #950 from daleglass-overte/fix-warnings
Fix C++20 warnings
2024-05-04 19:40:21 +02:00
Dale Glass
84b16f44aa Fix ignored return value warning
warning: ignoring return value of ‘std::lock_guard<_Mutex>::lock_guard(mutex_type&) [with _Mutex = std::mutex; mutex_type = std::mutex]’, declared with attribute ‘nodiscard’ [-Wunused-result]

This may mean the lock wasn't actually being taken.
2024-05-04 16:15:09 +02:00
Dale Glass
9cb35541d3 Fix -Wtemplate-id-cdtor
warning: template-id not allowed for constructor in C++20 [-Wtemplate-id-cdtor]
2024-05-04 15:56:06 +02:00
Dale Glass
fe550aa69f Whitespace changes 2024-05-04 15:56:06 +02:00
HifiExperiments
19144e492c
Merge pull request #152 from HifiExperiments/urls
add canViewAssetURLs domain permissions
2024-05-01 16:49:38 -07:00
HifiExperiments
46787eebf0
Merge pull request #853 from overte-org/fix/script_deadlocks
Move helper script engines to their own threads
2024-04-30 13:30:27 -07:00
HifiExperiments
268de192f7
Merge branch 'master' into fix/script_deadlocks 2024-04-30 13:29:17 -07:00
2010bb44e8
Simplify ScriptableAvatar.cpp helper script engine lambda
Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com>
2024-04-30 16:27:57 +02:00
9f80c9de58 Added HelperScriptEngine class 2024-04-30 00:27:19 +02:00
HifiExperiments
ed88ab5ecb
Merge pull request #936 from HifiExperiments/mtoon2
support VRMC_materials_mtoon and KHR_materials_unlit
2024-04-19 23:01:41 -07:00
HifiExperiments
74002b4738 simplify constructors 2024-04-19 16:05:59 -07:00
HifiExperiments
58e84acd5f whoops now it's working 2024-04-18 18:10:48 -07:00
HifiExperiments
a58e188b5c always allow getting my own avatar entities, also whoops I missed some group props 2024-04-18 17:19:06 -07:00
HifiExperiments
8a770094bb cleanup 2024-04-18 15:50:10 -07:00
HifiExperiments
f3cb4e2ca9 handle canViewAssetURLs better in create 2024-04-18 15:44:19 -07:00
HifiExperiments
bf03847549 apply madder's patch 2024-04-18 15:44:19 -07:00
HifiExperiments
8bdc5bb4cf add canViewAssetURLs domain permissions 2024-04-18 15:44:15 -07:00
HifiExperiments
edb8cc55b4
Merge pull request #887 from overte-org/feature/script_security
Added simple protection for avatar URL
2024-04-18 15:16:27 -07:00
HifiExperiments
022f1497c5
Merge pull request #927 from HifiExperiments/groupProps
Fix getEntityProperties for group properties + keylight direction
2024-04-18 13:14:30 -07:00
HifiExperiments
376cd078e5
Merge pull request #935 from HifiExperiments/jointName
conversionPenaltyScore should accumulate
2024-04-18 12:56:34 -07:00
HifiExperiments
b22f5fe4fe
Merge pull request #899 from HifiExperiments/refresh-rate
Custom refresh rate profile
2024-04-17 14:46:36 -07:00
5aac93352c Fixed check for if script permission is enabled 2024-04-17 00:45:57 +02:00
46a80fcfdb
Merge pull request #868 from overte-org/feature/script_byte_array
Add qByteArray to script value conversion
2024-04-16 22:34:44 +02:00
HifiExperiments
8f27a4bf2b support VRMC_materials_mtoon and KHR_materials_unlit 2024-04-14 16:23:45 -07:00
95406c44c6 Simplified ScriptSecurity.qml 2024-04-14 21:56:41 +02:00
1887a82b4b Script security fixes and cleanups 2024-04-14 20:22:22 +02:00
e57874a2bd
Simplify ScriptAvatarData::getSkeletonModelURLFromScript
Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com>
2024-04-14 18:12:30 +02:00
379db8b17c
Simplify AvatarData::getSkeletonModelURLFromScript()
Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com>
2024-04-14 18:11:27 +02:00
HifiExperiments
426df9dc94 conversionPenaltyScore should accumulate 2024-04-13 14:13:44 -07:00
HifiExperiments
b8a9881d41 fix getting only group properties + keylight.direction typo 2024-04-11 15:07:03 -07:00
HifiExperiments
750c5f20f6 cleanup, fixes, update QML 2024-03-29 21:37:57 -07:00
latex
a6646d8dff Custom refresh rate profile WIP
This adds a Custom refresh rate profile with configurable refresh rate regimes.

Unfortunately this commit does not work yet. The SpinBoxes inside GraphicsSettings are on top of each other, and changing the values for the Custom profile through e.g. the JS API does not actually affect the refresh rate cap at all for some reason.
2024-03-29 21:37:50 -07:00
f1475e49ee
Merge pull request #865 from AleziaKurdis/CreateAppCopyID
Create app: Entity List: "Copy ID" on menu and contextual menu.
2024-03-29 22:30:28 +01:00
HifiExperiments
c41c2deb77
Merge pull request #863 from AleziaKurdis/CreateAppDimensionsCopyPaste
Create App.: "Copy Dimensions" and "Paste Dimensions"
2024-03-29 13:02:55 -07:00
HifiExperiments
cc8133bf08
Merge branch 'master' into CreateAppDimensionsCopyPaste 2024-03-29 13:01:04 -07:00
HifiExperiments
7500a74e2b
Merge pull request #882 from overte-org/fix/oculus_full_body
Add Oculus to fullbody-enabled headsets list
2024-03-27 23:14:23 -07:00
36b6010c08
Merge pull request #893 from overte-org/fix/agent_textures
Fix previous commit for not loading textures on agent
2024-03-27 00:25:14 +01:00
edb3580520 Fixed emtpy texture issue 2024-03-26 21:24:02 +01:00
65387adee8 Reapply "Disabled texture loading for agent"
This reverts commit bf601dfa6e.
2024-03-26 21:06:11 +01:00
d44ae7a961
Merge pull request #892 from overte-org/fix/avatar_textures
Revert "Disabled texture loading for agent"
2024-03-26 18:08:31 +01:00
bf601dfa6e Revert "Disabled texture loading for agent"
This reverts commit a0aae43386.
2024-03-26 17:40:03 +01:00
5f0f03af0a Fixed private settings bug 2024-03-26 00:27:58 +01:00
7fdd4aef11
Merge pull request #854 from overte-org/fix/anim_reference
Fix invalid animation reference in assignment client
2024-03-25 22:34:32 +01:00
a0aae43386 Disabled texture loading for agent 2024-03-25 22:31:53 +01:00
076bd2dbee Added permissions to avatar bookmarks 2024-03-24 22:36:26 +01:00
16530b2334 Moved avatar URL to fully private settings 2024-03-23 20:41:22 +01:00
225578febe Added simple protection for avatar URL 2024-03-23 01:19:05 +01:00
922ae918e9
Merge pull request #877 from AleziaKurdis/CreateAppAdvancedImport
Create Application: Advanced Import functionality
2024-03-21 00:18:03 +01:00
aff59e5469
Merge pull request #880 from AleziaKurdis/CreateAppToolTabUiAdjustments
Create App: Tools tab: CSS&HTML adjustments
2024-03-20 21:02:31 +01:00
Alezia Kurdis
ef6f2737b6
adjustment
adjustment
2024-03-19 20:26:27 -04:00
Alezia Kurdis
74b9561afe
adjustment
adjustment
2024-03-19 20:26:01 -04:00
9106746bc9 Add Oculus to fullbody-enabled headsets list 2024-03-19 22:13:39 +01:00
Alezia Kurdis
7734357398
Tools Tab html/css adjustments
Tools Tab html/css adjustments
2024-03-18 22:52:05 -04:00
Alezia Kurdis
3bc04c9c06
Delete scripts/system/html/edit-style.css
Comitted at the wrong level.
2024-03-18 22:50:56 -04:00
Alezia Kurdis
ca4dde4bb1
Fix css of Tools tab
Fix css of Tools tab
2024-03-17 23:24:49 -04:00
Dale Glass
ff91b93ed8
Merge pull request #870 from daleglass-overte/change-vircadia-launcher-dir
Change vircadia launcher dir
2024-03-16 22:32:04 +01:00
Dale Glass
9c823a8534
Merge pull request #869 from daleglass-overte/change-vircadia-fingerprint
Change the hash salt from Vircadia to Overte
2024-03-16 22:31:33 +01:00
Alezia Kurdis
a509f84a42
Add "Import" Tab
Add "Import" Tab
2024-03-16 14:05:14 -04:00
Alezia Kurdis
f50101db8a
Add "Import" Tab
Add "Import" Tab
2024-03-16 14:04:24 -04:00
854d80aace
Merge pull request #873 from daleglass-overte/warnings-as-errors-msvc
Fix warnings as errors for MSVC
2024-03-16 12:09:45 +01:00
Dale Glass
40761fb545 Fix warnings as errors for MSVC 2024-03-16 00:40:33 +01:00
3d5afbdd31
Merge pull request #845 from HifiExperiments/colorBleed
Clean up GeometryCache and remove _glColor4f
2024-03-15 03:07:08 +01:00
c50a4f9cb8 Added Base64 conversion functions 2024-03-15 00:17:41 +01:00
Dale Glass
65f55dd5fb Change Vircadia launcher directory to Overte 2024-03-14 22:36:38 +01:00
Dale Glass
2e7b19ea40 Change the hash salt from Vircadia to Overte 2024-03-14 22:35:40 +01:00
38caf617a2
Merge pull request #867 from overte-org/fix/gltf_collisions
Fix collisions on glTF avatars
2024-03-14 22:22:19 +01:00
ef4c99b027 Add qByteArray to script value conversion 2024-03-14 01:49:55 +01:00
58a7819fef
Merge pull request #864 from AnotherFoxGuy/no-screeshare
🔧 Disable building electron screenshare app on windows
2024-03-14 00:17:45 +01:00
03dbbb94c8
Merge pull request #866 from AnotherFoxGuy/fix-avatarcolision
🐛 Fixed avatar bounding box being inverted
2024-03-14 00:00:03 +01:00
6f8f32d802 Fix collisions on glTF avatars.
Co-authored-by: Edgar <Edgar@AnotherFoxGuy.com>
2024-03-13 22:40:17 +01:00
HifiExperiments
be95d324cc fix auto casts, offset 2024-03-12 21:36:59 -07:00
Alezia Kurdis
7c8044d27b
Copy ID(s) on multiple selection
Copy ID(s) on multiple selection
2024-03-12 21:36:45 -04:00
Alezia Kurdis
e29549e711
Copy ID(s) on multiple selection
Copy ID(s) on multiple selection
2024-03-12 21:36:03 -04:00
Alezia Kurdis
ad3236ba37
Copy ID(s) on multiple selection
Copy ID(s) on multiple selection
2024-03-12 21:35:25 -04:00
Alezia Kurdis
0c868bd416
Copy ID(s) on multiple selection
Copy ID(s) on multiple selection
2024-03-12 21:34:40 -04:00
Edgar
e27696802b
🐛 Fixed avatar bounding box being inverted 2024-03-12 22:12:03 +01:00
Alezia Kurdis
8b35693701
Adjust CSS for contextual menu of EntityList
Adjust CSS for contextual menu of EntityList
2024-03-11 23:01:35 -04:00
Alezia Kurdis
94a229b9e7
Add "Copy ID" 2024-03-11 22:37:24 -04:00
Alezia Kurdis
6bee693d0c
Add "Copy ID" 2024-03-11 22:36:38 -04:00
Alezia Kurdis
2f3aefc926
Add "Copy ID" 2024-03-11 22:36:01 -04:00
Alezia Kurdis
e802d0ec12
Add "Copy ID"
Add "Copy ID" on entity list menu and contextual menu.
2024-03-11 22:35:03 -04:00
Edgar
dac3006d8b
🔧 Disable building electron screenshare app on windows 2024-03-11 20:55:56 +01:00
Alezia Kurdis
4595d94bfe
Add Dimensions Copy Paste
Add Dimensions Copy Paste
2024-03-10 22:24:54 -04:00
Alezia Kurdis
9acd1a93c1
Add Dimensions Copy Paste
Add Dimensions Copy Paste
2024-03-10 22:23:49 -04:00
634dc64f8f
Merge pull request #844 from HifiExperiments/opaqueParticles
Support opaque (and black) particles
2024-03-10 21:16:29 +01:00
78978c7097 Initial fix for animations 2024-03-09 18:33:07 +01:00
bd14f39f66
Merge pull request #860 from overte-org/feature/gltf_webp
Added WebP support for binary glTF
2024-03-09 17:33:11 +01:00
347987591f Added WebP support for binary glTF 2024-03-09 00:54:40 +01:00
HifiExperiments
7b4c26be84 fix custom shape key shadows + render layers 2024-03-05 20:05:02 -08:00
805cd78728 Switched to animation frames reference 2024-03-06 00:35:19 +01:00
HifiExperiments
903984f427 try to fix amd deferred bug 2024-03-05 14:34:54 -08:00
HifiExperiments
3daa40087e support opaque (and black) particles 2024-03-05 14:34:54 -08:00
cd8ad23dd1 Fix invalid reference 2024-03-05 01:15:32 +01:00
93a243d095 Move helper script engines to their own threads 2024-03-04 23:06:26 +01:00
HifiExperiments
f27263cc6a clean up geometrycache and remove _glColor4f 2024-03-01 13:47:36 -08:00
173 changed files with 5374 additions and 1488 deletions

View file

@ -1,6 +1,6 @@
# Copyright 2013-2019 High Fidelity, Inc.
# Copyright 2020-2022 Vircadia contributors.
# Copyright 2021-2023 Overte e.V.
# Copyright 2021-2024 Overte e.V.
# SPDX-License-Identifier: Apache-2.0
name: Linux Server CI Build
@ -65,6 +65,16 @@ jobs:
arch: aarch64
runner: linux_aarch64
- os: ubuntu-24.04
image: docker.io/overte/overte-server-build:0.1.3-ubuntu-24.04-amd64
arch: amd64
runner: linux_amd64
- os: ubuntu-24.04
image: docker.io/overte/overte-server-build:0.1.3-ubuntu-24.04-aarch64
arch: aarch64
runner: linux_aarch64
- os: fedora-38
image: docker.io/overte/overte-server-build:0.1.3-fedora-38-amd64
arch: amd64
@ -75,15 +85,16 @@ jobs:
arch: aarch64
runner: linux_aarch64
- os: fedora-39
image: docker.io/overte/overte-server-build:0.1.4-fedora-39-amd64
arch: amd64
runner: linux_amd64
# Packaging broken; See: https://github.com/overte-org/overte/issues/968
#~ - os: fedora-39
#~ image: docker.io/overte/overte-server-build:0.1.4-fedora-39-amd64
#~ arch: amd64
#~ runner: linux_amd64
- os: fedora-39
image: docker.io/overte/overte-server-build:0.1.4-fedora-39-aarch64
arch: aarch64
runner: linux_aarch64
#~ - os: fedora-39
#~ image: docker.io/overte/overte-server-build:0.1.4-fedora-39-aarch64
#~ arch: aarch64
#~ runner: linux_aarch64
- os: rockylinux-9
image: docker.io/overte/overte-server-build:0.1.3-rockylinux-9-amd64

View file

@ -184,8 +184,13 @@ if(OVERTE_WARNINGS_WHITELIST)
endif()
if(OVERTE_WARNINGS_AS_ERRORS)
set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} -Werror")
set(ENV{CFLAGS} "$ENV{CXXFLAGS} -Werror")
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "" AND WIN32))
set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} /WX")
set(ENV{CFLAGS} "$ENV{CXXFLAGS} /WX")
else()
set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} -Werror")
set(ENV{CFLAGS} "$ENV{CXXFLAGS} -Werror")
endif()
endif()
@ -252,9 +257,6 @@ else()
endif()
set(SCREENSHARE 0)
if (WIN32)
set(SCREENSHARE 1)
endif()
if (APPLE AND NOT CLIENT_ONLY)
# Don't include Screenshare in OSX client-only builds.
set(SCREENSHARE 1)

View file

@ -109,7 +109,7 @@ public class PermissionChecker extends Activity {
JSONObject obj = new JSONObject();
try {
obj.put("firstRun",false);
obj.put("Avatar/fullAvatarURL", avatarPaths[which]);
obj.put(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/Avatar/fullAvatarURL", avatarPaths[which]);
File directory = new File(pathForJson);
if(!directory.exists()) directory.mkdirs();

View file

@ -40,7 +40,7 @@
*/
class AgentScriptingInterface : public QObject {
Q_OBJECT
Q_PROPERTY(bool isAvatar READ isAvatar WRITE setIsAvatar)
Q_PROPERTY(bool isAvatar READ getIsAvatar WRITE setIsAvatar)
Q_PROPERTY(bool isPlayingAvatarSound READ isPlayingAvatarSound)
Q_PROPERTY(bool isListeningToAudioStream READ isListeningToAudioStream WRITE setIsListeningToAudioStream)
Q_PROPERTY(bool isNoiseGateEnabled READ isNoiseGateEnabled WRITE setIsNoiseGateEnabled)
@ -77,15 +77,15 @@ public slots:
/*@jsdoc
* Checks whether the script is emulating an avatar.
* @function Agent.isAvatar
* @function Agent.getIsAvatar
* @returns {boolean} <code>true</code> if the script is emulating an avatar, otherwise <code>false</code>.
* @example <caption>Check whether the agent is emulating an avatar.</caption>
* (function () {
* print("Agent is avatar: " + Agent.isAvatar());
* print("Agent is avatar: " + Agent.getIsAvatar());
* print("Agent is avatar: " + Agent.isAvatar); // Same result.
* }());
*/
bool isAvatar() const { return _agent->isAvatar(); }
bool getIsAvatar() const { return _agent->isAvatar(); }
/*@jsdoc
* Plays a sound from the position and with the orientation of the emulated avatar's head. No sound is played unless

View file

@ -30,8 +30,12 @@
#include <NetworkingConstants.h>
ScriptableAvatar::ScriptableAvatar(): _scriptEngine(newScriptEngine()) {
ScriptableAvatar::ScriptableAvatar() {
_clientTraitsHandler.reset(new ClientTraitsHandler(this));
static std::once_flag once;
std::call_once(once, [] {
qRegisterMetaType<HFMModel::Pointer>("HFMModel::Pointer");
});
}
QByteArray ScriptableAvatar::toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking) {
@ -52,6 +56,7 @@ void ScriptableAvatar::startAnimation(const QString& url, float fps, float prior
_animation = DependencyManager::get<AnimationCache>()->getAnimation(url);
_animationDetails = AnimationDetails("", QUrl(url), fps, 0, loop, hold, false, firstFrame, lastFrame, true, firstFrame, false);
_maskedJoints = maskedJoints;
_isAnimationRigValid = false;
}
void ScriptableAvatar::stopAnimation() {
@ -89,11 +94,12 @@ QStringList ScriptableAvatar::getJointNames() const {
}
void ScriptableAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
_bind.reset();
_animSkeleton.reset();
_avatarAnimSkeleton.reset();
_geometryResource.reset();
AvatarData::setSkeletonModelURL(skeletonModelURL);
updateJointMappings();
_isRigValid = false;
}
int ScriptableAvatar::sendAvatarDataPacket(bool sendAll) {
@ -137,65 +143,87 @@ static AnimPose composeAnimPose(const HFMJoint& joint, const glm::quat rotation,
}
void ScriptableAvatar::update(float deltatime) {
if (!_geometryResource && !_skeletonModelFilenameURL.isEmpty()) { // AvatarData will parse the .fst, but not get the .fbx skeleton.
_geometryResource = DependencyManager::get<ModelCache>()->getGeometryResource(_skeletonModelFilenameURL);
}
// Run animation
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) {
if (!_animSkeleton) {
_animSkeleton = std::make_shared<AnimSkeleton>(_bind->getHFMModel());
}
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
while (currentFrame >= _animationDetails.lastFrame) {
currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
Q_ASSERT(QThread::currentThread() == thread());
if (_animation && _animation->isLoaded()) {
Q_ASSERT(thread() == _animation->thread());
auto frames = _animation->getFramesReference();
if (frames.size() > 0 && _geometryResource && _geometryResource->isHFMModelLoaded()) {
if (!_isRigValid) {
_rig.reset(_geometryResource->getHFMModel());
_isRigValid = true;
}
_animationDetails.currentFrame = currentFrame;
const QVector<HFMJoint>& modelJoints = _bind->getHFMModel().joints;
QStringList animationJointNames = _animation->getJointNames();
const int nJoints = modelJoints.size();
if (_jointData.size() != nJoints) {
_jointData.resize(nJoints);
if (!_isAnimationRigValid) {
_animationRig.reset(_animation->getHFMModel());
_isAnimationRigValid = true;
}
const int frameCount = _animation->getFrames().size();
const HFMAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
const HFMAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
const float frameFraction = glm::fract(currentFrame);
std::vector<AnimPose> poses = _animSkeleton->getRelativeDefaultPoses();
const float UNIT_SCALE = 0.01f;
for (int i = 0; i < animationJointNames.size(); i++) {
const QString& name = animationJointNames[i];
// As long as we need the model preRotations anyway, let's get the jointIndex from the bind skeleton rather than
// trusting the .fst (which is sometimes not updated to match changes to .fbx).
int mapping = _bind->getHFMModel().getJointIndex(name);
if (mapping != -1 && !_maskedJoints.contains(name)) {
AnimPose floorPose = composeAnimPose(modelJoints[mapping], floorFrame.rotations[i], floorFrame.translations[i] * UNIT_SCALE);
AnimPose ceilPose = composeAnimPose(modelJoints[mapping], ceilFrame.rotations[i], floorFrame.translations[i] * UNIT_SCALE);
blend(1, &floorPose, &ceilPose, frameFraction, &poses[mapping]);
}
if (!_avatarAnimSkeleton) {
_avatarAnimSkeleton = std::make_shared<AnimSkeleton>(_geometryResource->getHFMModel());
}
std::vector<AnimPose> absPoses = poses;
_animSkeleton->convertRelativePosesToAbsolute(absPoses);
for (int i = 0; i < nJoints; i++) {
JointData& data = _jointData[i];
AnimPose& absPose = absPoses[i];
if (data.rotation != absPose.rot()) {
data.rotation = absPose.rot();
data.rotationIsDefaultPose = false;
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
while (currentFrame >= _animationDetails.lastFrame) {
currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
}
AnimPose& relPose = poses[i];
if (data.translation != relPose.trans()) {
data.translation = relPose.trans();
data.translationIsDefaultPose = false;
}
}
_animationDetails.currentFrame = currentFrame;
} else {
_animation.clear();
const QVector<HFMJoint>& modelJoints = _geometryResource->getHFMModel().joints;
QStringList animationJointNames = _animation->getJointNames();
const int nJoints = modelJoints.size();
if (_jointData.size() != nJoints) {
_jointData.resize(nJoints);
}
const int frameCount = frames.size();
const HFMAnimationFrame& floorFrame = frames.at((int)glm::floor(currentFrame) % frameCount);
const HFMAnimationFrame& ceilFrame = frames.at((int)glm::ceil(currentFrame) % frameCount);
const float frameFraction = glm::fract(currentFrame);
std::vector<AnimPose> poses = _avatarAnimSkeleton->getRelativeDefaultPoses();
// TODO: this needs more testing, it's possible that we need not only scale but also rotation and translation
// According to tests with unmatching avatar and animation armatures, sometimes bones are not rotated correctly.
// Matching armatures already work very well now.
const float UNIT_SCALE = _animationRig.GetScaleFactorGeometryToUnscaledRig() / _rig.GetScaleFactorGeometryToUnscaledRig();
for (int i = 0; i < animationJointNames.size(); i++) {
const QString& name = animationJointNames[i];
// As long as we need the model preRotations anyway, let's get the jointIndex from the bind skeleton rather than
// trusting the .fst (which is sometimes not updated to match changes to .fbx).
int mapping = _geometryResource->getHFMModel().getJointIndex(name);
if (mapping != -1 && !_maskedJoints.contains(name)) {
AnimPose floorPose = composeAnimPose(modelJoints[mapping], floorFrame.rotations[i],
floorFrame.translations[i] * UNIT_SCALE);
AnimPose ceilPose = composeAnimPose(modelJoints[mapping], ceilFrame.rotations[i],
ceilFrame.translations[i] * UNIT_SCALE);
blend(1, &floorPose, &ceilPose, frameFraction, &poses[mapping]);
}
}
std::vector<AnimPose> absPoses = poses;
Q_ASSERT(_avatarAnimSkeleton != nullptr);
_avatarAnimSkeleton->convertRelativePosesToAbsolute(absPoses);
for (int i = 0; i < nJoints; i++) {
JointData& data = _jointData[i];
AnimPose& absPose = absPoses[i];
if (data.rotation != absPose.rot()) {
data.rotation = absPose.rot();
data.rotationIsDefaultPose = false;
}
AnimPose& relPose = poses[i];
if (data.translation != relPose.trans()) {
data.translation = relPose.trans();
data.translationIsDefaultPose = false;
}
}
} else {
_animation.clear();
}
}
}
@ -245,6 +273,7 @@ void ScriptableAvatar::setJointMappingsFromNetworkReply() {
networkReply->deleteLater();
return;
}
// TODO: this works only with .fst files currently, not directly with FBX and GLB models
{
QWriteLocker writeLock(&_jointDataLock);
QByteArray line;
@ -253,7 +282,7 @@ void ScriptableAvatar::setJointMappingsFromNetworkReply() {
if (line.startsWith("filename")) {
int filenameIndex = line.indexOf('=') + 1;
if (filenameIndex > 0) {
_skeletonFBXURL = _skeletonModelURL.resolved(QString(line.mid(filenameIndex).trimmed()));
_skeletonModelFilenameURL = _skeletonModelURL.resolved(QString(line.mid(filenameIndex).trimmed()));
}
}
if (!line.startsWith("jointIndex")) {
@ -315,7 +344,9 @@ AvatarEntityMap ScriptableAvatar::getAvatarEntityDataInternal(bool allProperties
EntityItemProperties properties = entity->getProperties(desiredProperties);
QByteArray blob;
EntityItemProperties::propertiesToBlob(*_scriptEngine, sessionID, properties, blob, allProperties);
_helperScriptEngine.run( [&] {
EntityItemProperties::propertiesToBlob(*_helperScriptEngine.get(), sessionID, properties, blob, allProperties);
});
data[id] = blob;
}
});
@ -339,8 +370,12 @@ void ScriptableAvatar::setAvatarEntityData(const AvatarEntityMap& avatarEntityDa
while (dataItr != avatarEntityData.end()) {
EntityItemProperties properties;
const QByteArray& blob = dataItr.value();
if (!blob.isNull() && EntityItemProperties::blobToProperties(*_scriptEngine, blob, properties)) {
newProperties[dataItr.key()] = properties;
if (!blob.isNull()) {
_helperScriptEngine.run([&] {
if (EntityItemProperties::blobToProperties(*_helperScriptEngine.get(), blob, properties)) {
newProperties[dataItr.key()] = properties;
}
});
}
++dataItr;
}
@ -419,9 +454,16 @@ void ScriptableAvatar::updateAvatarEntity(const QUuid& entityID, const QByteArra
EntityItemPointer entity;
EntityItemProperties properties;
if (!EntityItemProperties::blobToProperties(*_scriptEngine, entityData, properties)) {
// entityData is corrupt
return;
{
// TODO: checking how often this happens and what is the performance impact of having the script engine on separate thread
// If it's happening often, a method to move HelperScriptEngine into the current thread would be a good idea
bool result = _helperScriptEngine.runWithResult<bool> ( [&]() {
return EntityItemProperties::blobToProperties(*_helperScriptEngine.get(), entityData, properties);
});
if (!result) {
// entityData is corrupt
return;
}
}
std::map<QUuid, EntityItemPointer>::iterator itr = _entities.find(entityID);

View file

@ -19,6 +19,9 @@
#include <AvatarData.h>
#include <ScriptEngine.h>
#include <EntityItem.h>
#include "model-networking/ModelCache.h"
#include "Rig.h"
#include <HelperScriptEngine.h>
/*@jsdoc
* The <code>Avatar</code> API is used to manipulate scriptable avatars on the domain. This API is a subset of the
@ -217,12 +220,16 @@ private:
AnimationPointer _animation;
AnimationDetails _animationDetails;
QStringList _maskedJoints;
AnimationPointer _bind; // a sleazy way to get the skeleton, given the various library/cmake dependencies
std::shared_ptr<AnimSkeleton> _animSkeleton;
GeometryResource::Pointer _geometryResource;
Rig _rig;
bool _isRigValid{false};
Rig _animationRig;
bool _isAnimationRigValid{false};
std::shared_ptr<AnimSkeleton> _avatarAnimSkeleton;
QHash<QString, int> _fstJointIndices; ///< 1-based, since zero is returned for missing keys
QStringList _fstJointNames; ///< in order of depth-first traversal
QUrl _skeletonFBXURL;
mutable ScriptEnginePointer _scriptEngine;
QUrl _skeletonModelFilenameURL; // This contains URL from filename field in fst file
mutable HelperScriptEngine _helperScriptEngine;
std::map<QUuid, EntityItemPointer> _entities;
/// Loads the joint indices, names from the FST file (if any)

View file

@ -1,4 +1,4 @@
Source: hifi-client-deps
Version: 0.1
Description: Collected dependencies for High Fidelity applications
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr ((linux&!arm)|windows), quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator, discord-rpc (!android)
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr ((linux&!arm)|windows), openxr-loader, quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator, discord-rpc (!android)

View file

@ -0,0 +1,34 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO open-source-parsers/jsoncpp
REF "${VERSION}"
SHA512 1d06e044759b1e1a4cc4960189dd7e001a0a4389d7239a6d59295af995a553518e4e0337b4b4b817e70da5d9731a4c98655af90791b6287870b5ff8d73ad8873
HEAD_REF master
)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" JSONCPP_STATIC)
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" STATIC_CRT)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DJSONCPP_WITH_CMAKE_PACKAGE=ON
-DBUILD_STATIC_LIBS=${JSONCPP_STATIC}
-DJSONCPP_STATIC_WINDOWS_RUNTIME=${STATIC_CRT}
-DJSONCPP_WITH_PKGCONFIG_SUPPORT=ON
-DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF
-DJSONCPP_WITH_TESTS=OFF
-DJSONCPP_WITH_EXAMPLE=OFF
-DBUILD_OBJECT_LIBS=OFF
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/jsoncpp)
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
vcpkg_copy_pdbs()
vcpkg_fixup_pkgconfig()
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

View file

@ -0,0 +1,18 @@
{
"name": "jsoncpp",
"version": "1.9.5",
"port-version": 4,
"description": "JsonCpp is a C++ library that allows manipulating JSON values, including serialization and deserialization to and from strings. It can also preserve existing comment in unserialization/serialization steps, making it a convenient format to store user input files.",
"homepage": "https://github.com/open-source-parsers/jsoncpp",
"license": "MIT",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}

8
cmake/ports/node/portfile.cmake Executable file → Normal file
View file

@ -1,4 +1,4 @@
# Copyright 2023 Overte e.V.
# Copyright 2023-2024 Overte e.V.
# SPDX-License-Identifier: Apache-2.0
set(NODE_VERSION 18.14.2)
@ -28,9 +28,9 @@ else ()
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO nodejs/node
REF v18.16.1
SHA512 cd2d7871a1a2aca8d800e0a501bd2836cbce076de750dcfc0b2bbe602c8a23705154bfb12faa3ff78e25ec753f419220742228569c281fa458987fb24f6d4d09
HEAD_REF v18.16.1
REF v18.20.2
SHA512 10d3637c26274677d137f76bbb648d0e7851c994634a16c89858c3a13094a0692ea2cb9a787c6463c3001abd71dab0d83123127bc305171d097c48d21d691678
HEAD_REF v18.20.2
)
# node cannot configure out of source, which VCPKG expects. So we copy the source to the configure directory.
file(COPY ${SOURCE_PATH}/ DESTINATION "${CURRENT_BUILDTREES_DIR}")

View file

@ -0,0 +1,23 @@
From d80c7dc3f4810fc49e4444590d39ef71e8a9b01c Mon Sep 17 00:00:00 2001
From: Adam Johnson <AdamJohnso@gmail.com>
Date: Sat, 19 Feb 2022 19:42:31 -0500
Subject: [PATCH] Fix bad import in jinja2
---
external/python/jinja2/utils.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/external/python/jinja2/utils.py b/external/python/jinja2/utils.py
index db9c5d06..f198e3ef 100644
--- a/external/python/jinja2/utils.py
+++ b/external/python/jinja2/utils.py
@@ -639,4 +639,8 @@ def __repr__(self):
# Imported here because that's where it was in the past
-from markupsafe import Markup, escape, soft_unicode
+from markupsafe import Markup, escape
+try:
+ from markupsafe import soft_unicode
+except ImportError:
+ from markupsafe import soft_str as soft_unicode

View file

@ -0,0 +1,30 @@
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c75b145..386494c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -89,7 +89,7 @@ if(NOT VULKAN_INCOMPATIBLE)
endif()
find_package(Threads REQUIRED)
-find_package(JsonCpp)
+find_package(jsoncpp CONFIG REQUIRED)
### All options defined here
option(BUILD_LOADER "Build loader" ON)
diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt
index 6a88cf4..0821a3d 100644
--- a/src/loader/CMakeLists.txt
+++ b/src/loader/CMakeLists.txt
@@ -68,7 +68,11 @@ add_library(openxr_loader ${LIBRARY_TYPE}
${openxr_loader_RESOURCE_FILE}
)
if(BUILD_WITH_SYSTEM_JSONCPP)
- target_link_libraries(openxr_loader PRIVATE JsonCpp::JsonCpp)
+ if(BUILD_SHARED_LIBS)
+ target_link_libraries(openxr_loader PRIVATE jsoncpp_lib)
+ else()
+ target_link_libraries(openxr_loader PRIVATE jsoncpp_static)
+ endif()
else()
target_sources(openxr_loader
PRIVATE

View file

@ -0,0 +1,79 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO KhronosGroup/OpenXR-SDK
REF "release-${VERSION}"
SHA512 6efc7596e707f95366dbcdbac9bd7d0c20735a2175b4edf56a9e8a112cf0ab8b664069fe942313164a37119032ddbf5671bc88ab5f276005dd36e4a4dabba1c7
HEAD_REF master
PATCHES
fix-openxr-sdk-jsoncpp.patch
)
vcpkg_from_github(
OUT_SOURCE_PATH SDK_SOURCE_PATH
REPO KhronosGroup/OpenXR-SDK-Source
REF "release-${VERSION}"
SHA512 04bdb0f16078209b5edd175a3396f70e1ceb8cfa382c65b8fda388e565480e3844daf68e0d987e72ed8c21d3148af0b41a2170911ec1660565887e0e5ae6d2bf
HEAD_REF master
PATCHES
fix-openxr-sdk-jsoncpp.patch
fix-jinja2.patch
)
vcpkg_from_github(
OUT_SOURCE_PATH HPP_SOURCE_PATH
REPO KhronosGroup/OpenXR-hpp
REF 63db9919822f8af6f7bf7416ba6a015d4617202e
SHA512 9e768f485d1631f8e74f35f028a64e2d64e33d362c53ae1c54427a10786e3befdd24089927319aa1a4b4c3e010247bd6cb3394bcee460c467c637ab6bc7bec90
HEAD_REF master
PATCHES
python3_8_compatibility.patch
)
# Weird behavior inside the OpenXR loader. On Windows they force shared libraries to use static crt, and
# vice-versa. Might be better in future iterations to patch the CMakeLists.txt for OpenXR
if (VCPKG_TARGET_IS_UWP OR VCPKG_TARGET_IS_WINDOWS)
if(VCPKG_LIBRARY_LINKAGE STREQUAL static)
set(DYNAMIC_LOADER OFF)
set(VCPKG_CRT_LINKAGE dynamic)
else()
set(DYNAMIC_LOADER ON)
set(VCPKG_CRT_LINKAGE static)
endif()
endif()
vcpkg_find_acquire_program(PYTHON3)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DBUILD_API_LAYERS=OFF
-DBUILD_TESTS=OFF
-DBUILD_CONFORMANCE_TESTS=OFF
-DDYNAMIC_LOADER=${DYNAMIC_LOADER}
-DPYTHON_EXECUTABLE="${PYTHON3}"
-DBUILD_WITH_SYSTEM_JSONCPP=ON
)
vcpkg_cmake_install()
# Generate the OpenXR C++ bindings
set(ENV{OPENXR_REPO} "${SDK_SOURCE_PATH}")
vcpkg_execute_required_process(
COMMAND ${PYTHON3} "${HPP_SOURCE_PATH}/scripts/hpp_genxr.py" -quiet -registry "${SDK_SOURCE_PATH}/specification/registry/xr.xml" -o "${CURRENT_PACKAGES_DIR}/include/openxr"
WORKING_DIRECTORY "${HPP_SOURCE_PATH}"
LOGNAME "openxr-hpp"
)
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_cmake_config_fixup(PACKAGE_NAME OpenXR CONFIG_PATH cmake)
else()
vcpkg_cmake_config_fixup(PACKAGE_NAME OpenXR CONFIG_PATH lib/cmake/openxr)
endif()
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share")
vcpkg_fixup_pkgconfig()
vcpkg_copy_pdbs()
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)

View file

@ -0,0 +1,13 @@
diff --git a/scripts/hpp_genxr.py b/scripts/hpp_genxr.py
index ce419b0..23e1d3d 100644
--- a/scripts/hpp_genxr.py
+++ b/scripts/hpp_genxr.py
@@ -36,7 +36,7 @@ from xrconventions import OpenXRConventions
from data import EXCLUDED_EXTENSIONS
-def makeREstring(strings: Iterable[str], default: typing.Optional[str] = None) -> str:
+def makeREstring(strings, default: typing.Optional[str] = None) -> str:
"""Turn a list of strings into a regexp string matching exactly those strings."""
if strings or default is None:
return f"^({'|'.join(re.escape(s) for s in strings)})$"

View file

@ -0,0 +1,27 @@
{
"name": "openxr-loader",
"version": "1.0.31",
"description": "A royalty-free, open standard that provides high-performance access to Augmented Reality (AR) and Virtual Reality (VR)—collectively known as XR—platforms and devices",
"homepage": "https://github.com/KhronosGroup/OpenXR-SDK",
"license": "Apache-2.0",
"supports": "!uwp & !osx",
"dependencies": [
"jsoncpp",
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
],
"features": {
"vulkan": {
"description": "Vulkan functionality for OpenXR",
"dependencies": [
"vulkan"
]
}
}
}

View file

@ -1,5 +1,5 @@
{
"version": 2.6,
"version": 2.7,
"settings": [
{
"name": "metaverse",
@ -402,7 +402,7 @@
},
{
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether a user can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the &ldquo;locked&rdquo; property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain&rsquo;s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let&rsquo;s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>",
"span": 12
"span": 11
}
],
"columns": [
@ -479,6 +479,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
],
"non-deletable-row-key": "permissions_id",
@ -505,6 +512,7 @@
"id_can_rez_tmp": true,
"id_can_write_to_asset_server": true,
"id_can_get_and_set_private_user_data": true,
"id_can_view_asset_urls": true,
"permissions_id": "localhost"
},
{
@ -633,6 +641,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},
@ -752,6 +767,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},
@ -844,6 +866,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},
@ -936,6 +965,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},
@ -1022,13 +1058,20 @@
"editable": true,
"default": false
},
{
"name": "id_can_get_and_set_private_user_data",
"label": "Get and Set Private User Data",
"type": "checkbox",
"editable": true,
"default": false
}
{
"name": "id_can_get_and_set_private_user_data",
"label": "Get and Set Private User Data",
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},
{
@ -1120,6 +1163,13 @@
"type": "checkbox",
"editable": true,
"default": false
},
{
"name": "id_can_view_asset_urls",
"label": "View Asset URLs",
"type": "checkbox",
"editable": true,
"default": false
}
]
},

View file

@ -353,6 +353,7 @@ void DomainGatekeeper::updateNodePermissions() {
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
userPerms.permissions |= NodePermissions::Permission::canGetAndSetPrivateUserData;
userPerms.permissions |= NodePermissions::Permission::canRezAvatarEntities;
userPerms.permissions |= NodePermissions::Permission::canViewAssetURLs;
} else {
// at this point we don't have a sending socket for packets from this node - assume it is the active socket
// or the public socket if we haven't activated a socket for the node yet
@ -446,6 +447,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
userPerms.permissions |= NodePermissions::Permission::canGetAndSetPrivateUserData;
userPerms.permissions |= NodePermissions::Permission::canRezAvatarEntities;
userPerms.permissions |= NodePermissions::Permission::canViewAssetURLs;
newNode->setPermissions(userPerms);
return newNode;
}

View file

@ -547,6 +547,29 @@ void DomainServerSettingsManager::setupConfigMap(const QString& userConfigFilena
// No migration needed to version 2.6.
if (oldVersion < 2.7) {
// Default values for new canViewAssetURLs permission.
unpackPermissions();
std::list<std::unordered_map<NodePermissionsKey, NodePermissionsPointer>> permissionsSets{
_standardAgentPermissions.get(),
_agentPermissions.get(),
_ipPermissions.get(),
_macPermissions.get(),
_machineFingerprintPermissions.get(),
_groupPermissions.get(),
_groupForbiddens.get()
};
foreach (auto permissionsSet, permissionsSets) {
for (auto entry : permissionsSet) {
const auto& userKey = entry.first;
if (permissionsSet[userKey]->can(NodePermissions::Permission::canConnectToDomain)) {
permissionsSet[userKey]->set(NodePermissions::Permission::canViewAssetURLs);
}
}
}
packPermissions();
}
// write the current description version to our settings
*versionVariant = _descriptionVersion;

View file

@ -0,0 +1,35 @@
{
"name": "OpenXR Index to Actions",
"channels": [
{ "from": "Index.LeftHand", "to": "Standard.LeftHand" },
{ "from": "Index.RightHand", "to": "Standard.RightHand" },
{ "from": "Index.Head", "to" : "Standard.Head", "when" : [ "Application.InHMD"] },
{ "from": "Index.LeftPrimaryThumb", "to": "Actions.Down" },
{ "from": "Index.LeftPrimaryThumbTouch", "to": "Standard.LeftPrimaryThumbTouch" },
{ "from": "Index.LeftSecondaryThumb", "to": "Actions.ContextMenu" },
{ "from": "Index.LeftSecondaryThumbTouch", "to": "Standard.LeftSecondaryThumbTouch" },
{ "from": "Index.RightPrimaryThumb", "to": "Actions.Up" },
{ "from": "Index.RightPrimaryThumbTouch", "to": "Standard.RightPrimaryThumbTouch" },
{ "from": "Index.RightSecondaryThumb", "to": "Actions.Sprint" },
{ "from": "Index.RightSecondaryThumbTouch", "to": "Standard.RightSecondaryThumbTouch" },
{ "from": "Index.LY", "to": "Actions.TranslateZ", "filters": ["invert"] },
{ "from": "Index.LX", "to": "Actions.TranslateX" },
{ "from": "Index.RY", "to": "Standard.RY" },
{ "from": "Index.RX", "to": "Standard.RX" },
{ "from": "Index.LS", "to": "Standard.LS" },
{ "from": "Index.RS", "to": "Actions.CycleCamera" },
{ "from": "Index.LSTouch", "to": "Standard.LSTouch" },
{ "from": "Index.RSTouch", "to": "Standard.RSTouch" },
{ "from": "Index.RT", "to": "Standard.RT" },
{ "from": "Index.LT", "to": "Standard.LT" },
{ "from": "Index.RTClick", "to": "Standard.RTClick" },
{ "from": "Index.LTClick", "to": "Standard.LTClick" },
{ "from": "Index.LeftPrimaryIndexTouch", "to": "Standard.LeftPrimaryIndexTouch" },
{ "from": "Index.RightPrimaryIndexTouch", "to": "Standard.RightPrimaryIndexTouch" }
]
}

View file

@ -347,6 +347,10 @@ Flickable {
text: "Real-Time"
refreshRatePreset: 2 // RefreshRateProfile::REALTIME
}
ListElement {
text: "Custom"
refreshRatePreset: 3 // RefreshRateProfile::CUSTOM
}
}
HifiControlsUit.ComboBox {
@ -362,13 +366,7 @@ Flickable {
currentIndex: -1
function refreshRefreshRateDropdownDisplay() {
if (Performance.getRefreshRateProfile() === 0) {
refreshRateDropdown.currentIndex = 0;
} else if (Performance.getRefreshRateProfile() === 1) {
refreshRateDropdown.currentIndex = 1;
} else {
refreshRateDropdown.currentIndex = 2;
}
refreshRateDropdown.currentIndex = Performance.getRefreshRateProfile();
}
Component.onCompleted: {
@ -382,6 +380,180 @@ Flickable {
}
}
ColumnLayout {
width: parent.width
Layout.topMargin: 32
visible: refreshRateDropdown.currentIndex == 3
RowLayout {
Layout.margins: 8
HifiControlsUit.SpinBox {
id: refreshRateCustomFocusActive
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Focus Active"
realFrom: 1
realTo: 1000
realStepSize: 15
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(0)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(0, realValue)
}
}
}
HifiControlsUit.SpinBox {
id: refreshRateCustomFocusInactive
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Focus Inactive"
realFrom: 1
realTo: 1000
realStepSize: 15
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(1)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(1, realValue)
}
}
}
}
RowLayout {
Layout.margins: 8
HifiControlsUit.SpinBox {
id: refreshRateCustomUnfocus
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Unfocus"
realFrom: 1
realTo: 1000
realStepSize: 15
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(2)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(2, realValue);
}
}
}
HifiControlsUit.SpinBox {
id: refreshRateCustomMinimized
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Minimized"
realFrom: 1
realTo: 1000
realStepSize: 1
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(3)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(3, realValue)
}
}
}
}
RowLayout {
Layout.margins: 8
HifiControlsUit.SpinBox {
id: refreshRateCustomStartup
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Startup"
realFrom: 1
realTo: 1000
realStepSize: 15
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(4)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(4, realValue)
}
}
}
HifiControlsUit.SpinBox {
id: refreshRateCustomShutdown
decimals: 0
width: 160
height: 32
suffix: " FPS"
label: "Shutdown"
realFrom: 1
realTo: 1000
realStepSize: 15
realValue: 60
colorScheme: hifi.colorSchemes.dark
property var loaded: false
Component.onCompleted: {
realValue = Performance.getCustomRefreshRate(5)
loaded = true
}
onRealValueChanged: {
if (loaded) {
Performance.setCustomRefreshRate(5, realValue)
}
}
}
}
}
Item {
Layout.preferredWidth: parent.width
Layout.preferredHeight: 35

View file

@ -0,0 +1,152 @@
//
// ScriptPermissions.cpp
// libraries/script-engine/src/ScriptPermissions.cpp
//
// Created by dr Karol Suprynowicz on 2024/03/24.
// Copyright 2024 Overte e.V.
//
// Based on EntityScriptQMLWhitelist.qml
// Created by Kalila L. on 2019.12.05 | realities.dev | somnilibertas@gmail.com
// Copyright 2019 Kalila L.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// Security settings for the script engines
import Hifi 1.0 as Hifi
import QtQuick 2.8
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.12
import stylesUit 1.0 as HifiStylesUit
import controlsUit 1.0 as HiFiControls
import PerformanceEnums 1.0
import "../../../windows"
Rectangle {
id: parentBody;
function getWhitelistAsText() {
var whitelist = Settings.getValue("private/scriptPermissionGetAvatarURLSafeURLs");
var arrayWhitelist = whitelist.replace(",", "\n");
return arrayWhitelist;
}
function setWhitelistAsText(whitelistText) {
Settings.setValue("private/scriptPermissionGetAvatarURLSafeURLs", whitelistText.text);
notificationText.text = "Whitelist saved.";
}
function setAvatarProtection(enabled) {
Settings.setValue("private/scriptPermissionGetAvatarURLEnable", enabled);
console.info("Setting Protect Avatar URLs to:", enabled);
}
anchors.fill: parent
width: parent.width;
height: 120;
color: "#80010203";
HifiStylesUit.RalewayRegular {
id: titleText;
text: "Protect Avatar URLs"
// Text size
size: 24;
// Style
color: "white";
elide: Text.ElideRight;
// Anchors
anchors.top: parent.top;
anchors.left: parent.left;
anchors.leftMargin: 20;
anchors.right: parent.right;
anchors.rightMargin: 20;
height: 60;
CheckBox {
id: whitelistEnabled;
checked: Settings.getValue("private/scriptPermissionGetAvatarURLEnable", true);
anchors.right: parent.right;
anchors.top: parent.top;
anchors.topMargin: 10;
onToggled: {
setAvatarProtection(whitelistEnabled.checked)
}
Label {
text: "Enabled"
color: "white"
font.pixelSize: 18;
anchors.right: parent.left;
anchors.top: parent.top;
anchors.topMargin: 10;
}
}
}
Rectangle {
id: textAreaRectangle;
color: "black";
width: parent.width;
height: 250;
anchors.top: titleText.bottom;
ScrollView {
id: textAreaScrollView
anchors.fill: parent;
width: parent.width
height: parent.height
contentWidth: parent.width
contentHeight: parent.height
clip: false;
TextArea {
id: whitelistTextArea
text: getWhitelistAsText();
onTextChanged: notificationText.text = "";
width: parent.width;
height: parent.height;
font.family: "Ubuntu";
font.pointSize: 12;
color: "white";
}
}
Button {
id: saveChanges
anchors.topMargin: 5;
anchors.leftMargin: 20;
anchors.rightMargin: 20;
x: textAreaRectangle.x + textAreaRectangle.width - width - 15;
y: textAreaRectangle.y + textAreaRectangle.height - height;
contentItem: Text {
text: saveChanges.text
font.family: "Ubuntu";
font.pointSize: 12;
opacity: enabled ? 1.0 : 0.3
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
text: "Save Changes"
onClicked: setWhitelistAsText(whitelistTextArea)
HifiStylesUit.RalewayRegular {
id: notificationText;
text: ""
// Text size
size: 16;
// Style
color: "white";
elide: Text.ElideLeft;
// Anchors
anchors.right: parent.left;
anchors.rightMargin: 10;
}
}
}
}

View file

@ -3,6 +3,7 @@
//
// Created by Zach Fox on 2019-08-08
// Copyright 2019 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -78,7 +79,7 @@ Item {
temporaryText: "Viewing!"
onClicked: {
Qt.openUrlExternally("https://www.highfidelity.com/knowledge");
Qt.openUrlExternally("https://overte.org/");
}
}

View file

@ -3,6 +3,7 @@
//
// Created by Zach Fox on 2019-08-20
// Copyright 2019 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -76,7 +77,7 @@ Item {
temporaryText: "Opening browser..."
onClicked: {
Qt.openUrlExternally("https://www.highfidelity.com/knowledge/kb-tickets/new");
Qt.openUrlExternally("https://overte.org/contact.html");
}
}
}

View file

@ -3,6 +3,7 @@
//
// Created by Zach Fox on 2019-06-11
// Copyright 2019 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -93,9 +94,9 @@ Flickable {
width: parent.width
height: 18
labelTextOn: "Keep Old Menus (File, Edit, etc)"
checked: Settings.getValue("simplifiedUI/keepMenus", false);
checked: Settings.getValue("simplifiedUI/keepMenus", true);
onClicked: {
Settings.setValue("simplifiedUI/keepMenus", !Settings.getValue("simplifiedUI/keepMenus", false));
Settings.setValue("simplifiedUI/keepMenus", !Settings.getValue("simplifiedUI/keepMenus", true));
}
}

View file

@ -3,6 +3,7 @@
//
// Created by Zach Fox on 2019-05-06
// Copyright 2019 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -175,7 +176,7 @@ Flickable {
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
SimplifiedControls.RadioButton {
id: performanceLow
id: performanceLowPower
text: "Low Power Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.LOW_POWER ? " (Recommended)" : "")
checked: Performance.getPerformancePreset() === PerformanceEnums.LOW_POWER
onClicked: {

View file

@ -3,6 +3,7 @@
//
// Created by Zach Fox on 2019-05-08
// Copyright 2019 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -96,12 +97,11 @@ Original.Button {
}
}
contentItem: HifiStylesUit.FiraSansMedium {
contentItem: Text {
id: buttonText
//topPadding: -2 // Necessary for proper alignment using Graphik Medium
wrapMode: Text.Wrap
color: enabled ? simplifiedUI.colors.controls.button.text.enabled : simplifiedUI.colors.controls.button.text.disabled
size: simplifiedUI.sizes.controls.button.textSize
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: root.text

View file

@ -27,7 +27,7 @@ Item {
width: parent.width
property string title: "Controls"
property var openVRDevices: ["HTC Vive", "Valve Index", "Valve HMD", "Valve", "WindowsMR"]
property var openVRDevices: ["HTC Vive", "Valve Index", "Valve HMD", "Valve", "WindowsMR", "Oculus"]
HifiConstants { id: hifi }

View file

@ -3305,7 +3305,7 @@ void Application::initializeUi() {
// END PULL SAFEURLS FROM INTERFACE.JSON Settings
if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) {
if (QUrl(NetworkingConstants::OVERTE_COMMUNITY_APPLICATIONS).isParentOf(url)) {
return true;
} else {
for (const auto& str : safeURLS) {
@ -6942,51 +6942,40 @@ void Application::updateRenderArgs(float deltaTime) {
appRenderArgs._eyeToWorld = _myCamera.getTransform();
appRenderArgs._isStereo = false;
{
if (getActiveDisplayPlugin()->isStereo()) {
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
float ipdScale = hmdInterface->getIPDScale();
// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly.
ipdScale *= sensorToWorldScale;
float ipdScale = hmdInterface->getIPDScale() * sensorToWorldScale;
auto baseProjection = appRenderArgs._renderArgs.getViewFrustum().getProjection();
if (getActiveDisplayPlugin()->isStereo()) {
// Stereo modes will typically have a larger projection matrix overall,
// so we ask for the 'mono' projection matrix, which for stereo and HMD
// plugins will imply the combined projection for both eyes.
//
// This is properly implemented for the Oculus plugins, but for OpenVR
// and Stereo displays I'm not sure how to get / calculate it, so we're
// just relying on the left FOV in each case and hoping that the
// overall culling margin of error doesn't cause popping in the
// right eye. There are FIXMEs in the relevant plugins
_myCamera.setProjection(getActiveDisplayPlugin()->getCullingProjection(baseProjection));
appRenderArgs._isStereo = true;
// Stereo modes will typically have a larger projection matrix overall,
// so we ask for the 'mono' projection matrix, which for stereo and HMD
// plugins will imply the combined projection for both eyes.
//
// This is properly implemented for the Oculus plugins, but for OpenVR
// and Stereo displays I'm not sure how to get / calculate it, so we're
// just relying on the left FOV in each case and hoping that the
// overall culling margin of error doesn't cause popping in the
// right eye. There are FIXMEs in the relevant plugins
_myCamera.setProjection(getActiveDisplayPlugin()->getCullingProjection(baseProjection));
appRenderArgs._isStereo = true;
auto& eyeOffsets = appRenderArgs._eyeOffsets;
auto& eyeProjections = appRenderArgs._eyeProjections;
auto& eyeOffsets = appRenderArgs._eyeOffsets;
auto& eyeProjections = appRenderArgs._eyeProjections;
// FIXME we probably don't need to set the projection matrix every frame,
// only when the display plugin changes (or in non-HMD modes when the user
// changes the FOV manually, which right now I don't think they can.
for_each_eye([&](Eye eye) {
// For providing the stereo eye views, the HMD head pose has already been
// applied to the avatar, so we need to get the difference between the head
// pose applied to the avatar and the per eye pose, and use THAT as
// the per-eye stereo matrix adjustment.
mat4 eyeToHead = getActiveDisplayPlugin()->getEyeToHeadTransform(eye);
// Grab the translation
vec3 eyeOffset = glm::vec3(eyeToHead[3]);
// Apply IPD scaling
mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale);
eyeOffsets[eye] = eyeOffsetTransform;
eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection);
});
// FIXME we probably don't need to set the projection matrix every frame,
// only when the display plugin changes (or in non-HMD modes when the user
// changes the FOV manually, which right now I don't think they can.
for_each_eye([&](Eye eye) {
eyeOffsets[eye] = getActiveDisplayPlugin()->getEyeToHeadTransform(eye);
// Apply IPD scaling
eyeOffsets[eye][3][0] *= ipdScale;
eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection);
});
// Configure the type of display / stereo
appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR);
}
// Configure the type of display / stereo
appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR);
}
appRenderArgs._renderArgs._stencilMaskMode = getActiveDisplayPlugin()->getStencilMaskMode();

View file

@ -41,6 +41,15 @@
#include <QtQuick/QQuickWindow>
#include <memory>
#include "WarningsSuppression.h"
#include "ScriptPermissions.h"
QVariantMap AvatarBookmarks::getBookmarks() {
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
return _bookmarks;
} else {
return {};
}
}
void addAvatarEntities(const QVariantList& avatarEntities) {
auto nodeList = DependencyManager::get<NodeList>();
@ -123,6 +132,12 @@ AvatarBookmarks::AvatarBookmarks() {
}
void AvatarBookmarks::addBookmark(const QString& bookmarkName) {
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
addBookmarkInternal(bookmarkName);
}
}
void AvatarBookmarks::addBookmarkInternal(const QString& bookmarkName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "addBookmark", Q_ARG(QString, bookmarkName));
return;
@ -134,6 +149,12 @@ void AvatarBookmarks::addBookmark(const QString& bookmarkName) {
}
void AvatarBookmarks::saveBookmark(const QString& bookmarkName) {
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
saveBookmarkInternal(bookmarkName);
}
}
void AvatarBookmarks::saveBookmarkInternal(const QString& bookmarkName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "saveBookmark", Q_ARG(QString, bookmarkName));
return;
@ -145,6 +166,12 @@ void AvatarBookmarks::saveBookmark(const QString& bookmarkName) {
}
void AvatarBookmarks::removeBookmark(const QString& bookmarkName) {
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
removeBookmarkInternal(bookmarkName);
}
}
void AvatarBookmarks::removeBookmarkInternal(const QString& bookmarkName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "removeBookmark", Q_ARG(QString, bookmarkName));
return;
@ -200,6 +227,12 @@ void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) {
*/
void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
loadBookmarkInternal(bookmarkName);
}
}
void AvatarBookmarks::loadBookmarkInternal(const QString& bookmarkName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "loadBookmark", Q_ARG(QString, bookmarkName));
return;
@ -268,6 +301,15 @@ void AvatarBookmarks::readFromFile() {
}
QVariantMap AvatarBookmarks::getBookmark(const QString &bookmarkName)
{
if (ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL)) {
return getBookmarkInternal(bookmarkName);
} else {
return {};
}
}
QVariantMap AvatarBookmarks::getBookmarkInternal(const QString &bookmarkName)
{
if (QThread::currentThread() != thread()) {
QVariantMap result;

View file

@ -100,7 +100,7 @@ public slots:
* print("- " + key + " " + bookmarks[key].avatarUrl);
* };
*/
QVariantMap getBookmarks() { return _bookmarks; }
QVariantMap getBookmarks();
signals:
/*@jsdoc
@ -147,6 +147,11 @@ protected slots:
void deleteBookmark() override;
private:
QVariantMap getBookmarkInternal(const QString &bookmarkName);
void addBookmarkInternal(const QString& bookmarkName);
void saveBookmarkInternal(const QString& bookmarkName);
void loadBookmarkInternal(const QString& bookmarkName);
void removeBookmarkInternal(const QString& bookmarkName);
const QString AVATARBOOKMARKS_FILENAME = "avatarbookmarks.json";
const QString ENTRY_AVATAR_URL = "avatarUrl";
const QString ENTRY_AVATAR_ICON = "avatarIcon";

View file

@ -258,10 +258,11 @@ void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) {
// Display name and avatar
settings.beginGroup(AVATAR_GROUP);
displayName = settings.value(DISPLAY_NAME_KEY).toString();
fullAvatarURL = settings.value(FULL_AVATAR_URL_KEY).toUrl();
fullAvatarModelName = settings.value(FULL_AVATAR_MODEL_NAME_KEY).toString();
settings.endGroup();
fullAvatarURL = settings.value(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/" + AVATAR_GROUP + "/" + FULL_AVATAR_URL_KEY).toUrl();
// Tutorial complete
tutorialComplete = settings.value(TUTORIAL_COMPLETE_FLAG_KEY).toBool();
}
@ -280,12 +281,12 @@ void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) {
// Display name and avatar
settings.beginGroup(AVATAR_GROUP);
settings.setValue(DISPLAY_NAME_KEY, displayName);
settings.setValue(FULL_AVATAR_URL_KEY, fullAvatarURL);
settings.setValue(FULL_AVATAR_MODEL_NAME_KEY, fullAvatarModelName);
settings.endGroup();
settings.setValue(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/" + AVATAR_GROUP + "/" + FULL_AVATAR_URL_KEY, fullAvatarURL);
// Tutorial complete
settings.setValue(TUTORIAL_COMPLETE_FLAG_KEY, tutorialComplete);
}
}

View file

@ -49,10 +49,10 @@ LODManager::LODManager() {
const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec
// batchTIme is always contained in presentTime.
// We favor using batchTime instead of presentTime as a representative value for rendering duration (on present thread)
// We favor using batchTime instead of presentTime as a representative value for rendering duration (on present thread)
// if batchTime + cushionTime < presentTime.
// since we are shooting for fps around 60, 90Hz, the ideal frames are around 10ms
// so we are picking a cushion time of 3ms
// so we are picking a cushion time of 3ms
const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 3.0f; // msec
void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) {
@ -64,8 +64,8 @@ void LODManager::setRenderTimes(float presentTime, float engineRunTime, float ba
}
void LODManager::autoAdjustLOD(float realTimeDelta) {
std::lock_guard<std::mutex> { _automaticLODLock };
std::lock_guard<std::mutex> lock{ _automaticLODLock };
// The "render time" is the worse of:
// - engineRunTime: Time spent in the render thread in the engine producing the gpu::Frame N
// - batchTime: Time spent in the present thread processing the batches of gpu::Frame N+1
@ -92,7 +92,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f;
//Evaluate the running averages for the render time
// We must sanity check for the output average evaluated to be in a valid range to avoid issues
// We must sanity check for the output average evaluated to be in a valid range to avoid issues
_nowRenderTime = (1.0f - nowBlend) * _nowRenderTime + nowBlend * maxRenderTime; // msec
_nowRenderTime = std::max(0.0f, std::min(_nowRenderTime, (float)MSECS_PER_SECOND));
_smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec
@ -112,7 +112,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
// Current fps based on latest measurments
float currentNowFPS = (float)MSECS_PER_SECOND / _nowRenderTime;
float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime;
// Compute the Variance of the FPS signal (FPS - smouthFPS)^2
// Also scale it by a percentage for fine tuning (default is 100%)
float currentVarianceFPS = (currentSmoothFPS - currentNowFPS);
@ -165,7 +165,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
// Compute the output of the PID and record intermediate results for tuning
_pidOutputs.x = _pidCoefs.x * error; // Kp * error
_pidOutputs.y = _pidCoefs.y * integral; // Ki * integral
_pidOutputs.y = _pidCoefs.y * integral; // Ki * integral
_pidOutputs.z = _pidCoefs.z * derivative; // Kd * derivative
auto output = _pidOutputs.x + _pidOutputs.y + _pidOutputs.z;
@ -300,7 +300,7 @@ void LODManager::resetLODAdjust() {
}
void LODManager::setAutomaticLODAdjust(bool value) {
std::lock_guard<std::mutex> { _automaticLODLock };
std::lock_guard<std::mutex> lock{ _automaticLODLock };
_automaticLODAdjust = value;
saveSettings();
emit autoLODChanged();
@ -399,7 +399,7 @@ void LODManager::loadSettings() {
if (qApp->property(hifi::properties::OCULUS_STORE).toBool() && firstRun.get()) {
hmdQuality = WORLD_DETAIL_HIGH;
}
_automaticLODAdjust = automaticLODAdjust.get();
_lodHalfAngle = lodHalfAngle.get();
@ -457,7 +457,7 @@ float LODManager::getLODTargetFPS() const {
if (qApp->isHMDMode()) {
lodTargetFPS = getHMDLODTargetFPS();
}
// if RefreshRate is slower than LOD target then it becomes the true LOD target
if (lodTargetFPS > refreshRateFPS) {
return refreshRateFPS;
@ -476,7 +476,7 @@ void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMod
setDesktopLODTargetFPS(desiredFPS);
}
}
void LODManager::setWorldDetailQuality(WorldDetailQuality quality) {
setWorldDetailQuality(quality, qApp->isHMDMode());
saveSettings();
@ -492,7 +492,7 @@ ScriptValue worldDetailQualityToScriptValue(ScriptEngine* engine, const WorldDet
}
bool worldDetailQualityFromScriptValue(const ScriptValue& object, WorldDetailQuality& worldDetailQuality) {
worldDetailQuality =
worldDetailQuality =
static_cast<WorldDetailQuality>(std::min(std::max(object.toInt32(), (int)WORLD_DETAIL_LOW), (int)WORLD_DETAIL_HIGH));
return true;
}

View file

@ -323,6 +323,19 @@ Menu::Menu() {
}
});
// Settings > Script Security
action = addActionToQMenuAndActionHash(settingsMenu, MenuOption::ScriptSecurity);
connect(action, &QAction::triggered, [] {
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
auto hmd = DependencyManager::get<HMDScriptingInterface>();
tablet->pushOntoStack("hifi/dialogs/security/ScriptSecurity.qml");
if (!hmd->getShouldShowTablet()) {
hmd->toggleShouldShowTablet();
}
});
// Settings > Developer Menu
addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menu", 0, false, this, SLOT(toggleDeveloperMenus()));

View file

@ -190,6 +190,7 @@ namespace MenuOption {
const QString RunTimingTests = "Run Timing Tests";
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
const QString EntityScriptQMLWhitelist = "Entity Script / QML Whitelist";
const QString ScriptSecurity = "Script Security";
const QString ShowTrackedObjects = "Show Tracked Objects";
const QString SelfieCamera = "Selfie";
const QString SendWrongDSConnectVersion = "Send wrong DS connect version";

View file

@ -48,12 +48,13 @@ static const int VR_TARGET_RATE = 90;
* <tr><td><code>"Interactive"</code></td><td>Medium refresh rate, which is reduced when Interface doesn't have focus or is
* minimized.</td></tr>
* <tr><td><code>"Realtime"</code></td><td>High refresh rate, even when Interface doesn't have focus or is minimized.
* <tr><td><code>"Custom"</code></td><td>Custom refresh rate for full control over the refresh rate in all states.
* </tbody>
* </table>
* @typedef {string} RefreshRateProfileName
*/
static const std::array<std::string, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILE_TO_STRING =
{ { "Eco", "Interactive", "Realtime" } };
{ { "Eco", "Interactive", "Realtime", "Custom" } };
/*@jsdoc
* <p>Interface states that affect the refresh rate.</p>
@ -94,7 +95,8 @@ static const std::array<std::string, RefreshRateManager::UXMode::UX_NUM> UX_MODE
static const std::map<std::string, RefreshRateManager::RefreshRateProfile> REFRESH_RATE_PROFILE_FROM_STRING =
{ { "Eco", RefreshRateManager::RefreshRateProfile::ECO },
{ "Interactive", RefreshRateManager::RefreshRateProfile::INTERACTIVE },
{ "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME } };
{ "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME },
{ "Custom", RefreshRateManager::RefreshRateProfile::CUSTOM } };
// Porfile regimes are:
@ -107,10 +109,12 @@ static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM>
{ { 30, 20, 10, 2, 30, 30 } };
static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REALTIME_PROFILE =
{ { 60, 60, 60, 2, 30, 30} };
{ { 60, 60, 60, 2, 30, 30 } };
static const std::array<std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM>, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILES =
{ { ECO_PROFILE, INTERACTIVE_PROFILE, REALTIME_PROFILE } };
static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> CUSTOM_PROFILE = REALTIME_PROFILE; // derived from settings and modified by scripts below
static std::array<std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM>, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILES =
{ { ECO_PROFILE, INTERACTIVE_PROFILE, REALTIME_PROFILE, CUSTOM_PROFILE } };
static const int INACTIVE_TIMER_LIMIT = 3000;
@ -134,6 +138,10 @@ std::string RefreshRateManager::uxModeToString(RefreshRateManager::RefreshRateMa
RefreshRateManager::RefreshRateManager() {
_refreshRateProfile = (RefreshRateManager::RefreshRateProfile) _refreshRateProfileSetting.get();
for (size_t i = 0; i < _customRefreshRateSettings.size(); i++) {
REFRESH_RATE_PROFILES[CUSTOM][i] = _customRefreshRateSettings[i].get();
}
_inactiveTimer->setInterval(INACTIVE_TIMER_LIMIT);
_inactiveTimer->setSingleShot(true);
QObject::connect(_inactiveTimer.get(), &QTimer::timeout, [&] {
@ -168,6 +176,25 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr
}
}
int RefreshRateManager::getCustomRefreshRate(RefreshRateRegime regime) {
if (isValidRefreshRateRegime(regime)) {
return REFRESH_RATE_PROFILES[RefreshRateProfile::CUSTOM][regime];
}
return 0;
}
void RefreshRateManager::setCustomRefreshRate(RefreshRateRegime regime, int value) {
value = std::max(value, 1);
if (isValidRefreshRateRegime(regime)) {
_refreshRateProfileSettingLock.withWriteLock([&] {
REFRESH_RATE_PROFILES[RefreshRateProfile::CUSTOM][regime] = value;
_customRefreshRateSettings[regime].set(value);
});
updateRefreshRateController();
}
}
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
@ -191,7 +218,6 @@ void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateReg
_refreshRateRegime = refreshRateRegime;
updateRefreshRateController();
}
}
void RefreshRateManager::setUXMode(RefreshRateManager::UXMode uxMode) {

View file

@ -32,10 +32,11 @@ public:
ECO = 0,
INTERACTIVE,
REALTIME,
CUSTOM,
PROFILE_NUM
};
Q_ENUM(RefreshRateProfile)
static bool isValidRefreshRateProfile(RefreshRateProfile value) { return (value >= RefreshRateProfile::ECO && value <= RefreshRateProfile::REALTIME); }
static bool isValidRefreshRateProfile(RefreshRateProfile value) { return (value >= 0 && value < RefreshRateProfile::PROFILE_NUM); }
/*@jsdoc
* <p>Interface states that affect the refresh rate.</p>
@ -106,6 +107,9 @@ public:
// query the refresh rate target at the specified combination
int queryRefreshRateTarget(RefreshRateProfile profile, RefreshRateRegime regime, UXMode uxMode) const;
int getCustomRefreshRate(RefreshRateRegime regime);
void setCustomRefreshRate(RefreshRateRegime regime, int value);
void resetInactiveTimer();
void toggleInactive();
@ -121,7 +125,15 @@ private:
UXMode _uxMode { UXMode::DESKTOP };
mutable ReadWriteLockable _refreshRateProfileSettingLock;
Setting::Handle<int> _refreshRateProfileSetting { "refreshRateProfile", RefreshRateProfile::INTERACTIVE };
Setting::Handle<int> _refreshRateProfileSetting{ "refreshRateProfile", RefreshRateProfile::INTERACTIVE };
std::array<Setting::Handle<int>, REGIME_NUM> _customRefreshRateSettings { {
{ "customRefreshRateFocusActive", 60 },
{ "customRefreshRateFocusInactive", 60 },
{ "customRefreshRateUnfocus", 60 },
{ "customRefreshRateMinimized", 2 },
{ "customRefreshRateStartup", 30 },
{ "customRefreshRateShutdown", 30 }
} };
std::function<void(int)> _refreshRateOperator { nullptr };

View file

@ -333,6 +333,14 @@ void AvatarDoctor::diagnoseTextures() {
addTextureToList(material.occlusionTexture);
addTextureToList(material.scatteringTexture);
addTextureToList(material.lightmapTexture);
if (material.isMToonMaterial) {
addTextureToList(material.shadeTexture);
addTextureToList(material.shadingShiftTexture);
addTextureToList(material.matcapTexture);
addTextureToList(material.rimTexture);
addTextureToList(material.uvAnimationTexture);
}
}
for (const auto& materialMapping : model->getMaterialMapping()) {

View file

@ -136,6 +136,14 @@ AvatarProject* AvatarProject::createAvatarProject(const QString& projectsFolder,
addTextureToList(material.occlusionTexture);
addTextureToList(material.scatteringTexture);
addTextureToList(material.lightmapTexture);
if (material.isMToonMaterial) {
addTextureToList(material.shadeTexture);
addTextureToList(material.shadingShiftTexture);
addTextureToList(material.matcapTexture);
addTextureToList(material.rimTexture);
addTextureToList(material.uvAnimationTexture);
}
}
QDir textureDir(textureFolder.isEmpty() ? fbxInfo.absoluteDir() : textureFolder);

View file

@ -73,6 +73,7 @@
#include "MovingEntitiesOperator.h"
#include "SceneScriptingInterface.h"
#include "WarningsSuppression.h"
#include "ScriptPermissions.h"
using namespace std;
@ -226,7 +227,7 @@ MyAvatar::MyAvatar(QThread* thread) :
_yawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "yawSpeed", _yawSpeed),
_hmdYawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "hmdYawSpeed", _hmdYawSpeed),
_pitchSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "pitchSpeed", _pitchSpeed),
_fullAvatarURLSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarURL",
_fullAvatarURLSetting(QStringList() << SETTINGS_FULL_PRIVATE_GROUP_NAME << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarURL",
AvatarData::defaultFullAvatarModelUrl()),
_fullAvatarModelNameSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarModelName", _fullAvatarModelName),
_animGraphURLSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "animGraphURL", QUrl("")),
@ -1739,10 +1740,11 @@ void MyAvatar::handleChangedAvatarEntityData() {
blobFailed = true; // blob doesn't exist
return;
}
std::lock_guard<std::mutex> guard(_scriptEngineLock);
if (!EntityItemProperties::blobToProperties(*_scriptEngine, itr.value(), properties)) {
blobFailed = true; // blob is corrupt
}
_helperScriptEngine.run( [&] {
if (!EntityItemProperties::blobToProperties(*_helperScriptEngine.get(), itr.value(), properties)) {
blobFailed = true; // blob is corrupt
}
});
});
if (blobFailed) {
// remove from _cachedAvatarEntityBlobUpdatesToSkip just in case:
@ -1775,10 +1777,11 @@ void MyAvatar::handleChangedAvatarEntityData() {
skip = true;
return;
}
std::lock_guard<std::mutex> guard(_scriptEngineLock);
if (!EntityItemProperties::blobToProperties(*_scriptEngine, itr.value(), properties)) {
skip = true;
}
_helperScriptEngine.run( [&] {
if (!EntityItemProperties::blobToProperties(*_helperScriptEngine.get(), itr.value(), properties)) {
skip = true;
}
});
});
if (!skip && canRezAvatarEntites) {
sanitizeAvatarEntityProperties(properties);
@ -1883,10 +1886,9 @@ bool MyAvatar::updateStaleAvatarEntityBlobs() const {
if (found) {
++numFound;
QByteArray blob;
{
std::lock_guard<std::mutex> guard(_scriptEngineLock);
EntityItemProperties::propertiesToBlob(*_scriptEngine, getID(), properties, blob);
}
_helperScriptEngine.run( [&] {
EntityItemProperties::propertiesToBlob(*_helperScriptEngine.get(), getID(), properties, blob);
});
_avatarEntitiesLock.withWriteLock([&] {
_cachedAvatarEntityBlobs[id] = blob;
});
@ -1947,10 +1949,9 @@ AvatarEntityMap MyAvatar::getAvatarEntityData() const {
EntityItemProperties properties = entity->getProperties(desiredProperties);
QByteArray blob;
{
std::lock_guard<std::mutex> guard(_scriptEngineLock);
EntityItemProperties::propertiesToBlob(*_scriptEngine, getID(), properties, blob, true);
}
_helperScriptEngine.run( [&] {
EntityItemProperties::propertiesToBlob(*_helperScriptEngine.get(), getID(), properties, blob, true);
});
data[entityID] = blob;
}
@ -2092,9 +2093,6 @@ void MyAvatar::avatarEntityDataToJson(QJsonObject& root) const {
}
void MyAvatar::loadData() {
if (!_scriptEngine) {
_scriptEngine = newScriptEngine();
}
getHead()->setBasePitch(_headPitchSetting.get());
_yawSpeed = _yawSpeedSetting.get(_yawSpeed);
@ -2236,6 +2234,9 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString&
return attachment;
}
bool MyAvatar::isMyAvatarURLProtected() const {
return !ScriptPermissions::isCurrentScriptAllowed(ScriptPermissions::Permission::SCRIPT_PERMISSION_GET_AVATAR_URL);
}
int MyAvatar::parseDataFromBuffer(const QByteArray& buffer) {
qCDebug(interfaceapp) << "Error: ignoring update packet for MyAvatar"
@ -2700,11 +2701,10 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() {
QVariantMap avatarEntityData;
avatarEntityData["id"] = entityID;
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
{
std::lock_guard<std::mutex> guard(_scriptEngineLock);
ScriptValue scriptProperties = EntityItemPropertiesToScriptValue(_scriptEngine.get(), entityProperties);
_helperScriptEngine.run( [&] {
ScriptValue scriptProperties = EntityItemPropertiesToScriptValue(_helperScriptEngine.get(), entityProperties);
avatarEntityData["properties"] = scriptProperties.toVariant();
}
});
avatarEntitiesData.append(QVariant(avatarEntityData));
}
}

View file

@ -28,6 +28,7 @@
#include <controllers/Pose.h>
#include <controllers/Actions.h>
#include <EntityItem.h>
#include <HelperScriptEngine.h>
#include <ThreadSafeValueCache.h>
#include <Rig.h>
#include <SettingHandle.h>
@ -2683,6 +2684,7 @@ private:
void setEnableDrawAverageFacing(bool drawAverage) { _drawAverageFacingEnabled = drawAverage; }
bool getEnableDrawAverageFacing() const { return _drawAverageFacingEnabled; }
virtual bool isMyAvatar() const override { return true; }
virtual bool isMyAvatarURLProtected() const override;
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
virtual glm::vec3 getSkeletonPosition() const override;
int _skeletonModelChangeCount { 0 };
@ -3101,8 +3103,10 @@ private:
mutable std::set<EntityItemID> _staleCachedAvatarEntityBlobs;
//
// keep a ScriptEngine around so we don't have to instantiate on the fly (these are very slow to create/delete)
mutable std::mutex _scriptEngineLock;
ScriptEnginePointer _scriptEngine { nullptr };
// TODO: profile if it performs better when script engine is on avatar thread or on its own thread
// Own thread is safer from deadlocks
mutable HelperScriptEngine _helperScriptEngine;
bool _needToSaveAvatarEntitySettings { false };
bool _reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS] { false, false };

View file

@ -56,12 +56,22 @@ void PerformanceScriptingInterface::setRefreshRateProfile(RefreshRateProfile ref
emit settingsChanged();
}
void PerformanceScriptingInterface::setCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime, int value)
{
qApp->getRefreshRateManager().setCustomRefreshRate(refreshRateRegime, value);
emit settingsChanged();
}
int PerformanceScriptingInterface::getCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime) const {
return qApp->getRefreshRateManager().getCustomRefreshRate(refreshRateRegime);
}
PerformanceScriptingInterface::RefreshRateProfile PerformanceScriptingInterface::getRefreshRateProfile() const {
return (PerformanceScriptingInterface::RefreshRateProfile)qApp->getRefreshRateManager().getRefreshRateProfile();
}
QStringList PerformanceScriptingInterface::getRefreshRateProfileNames() const {
static const QStringList refreshRateProfileNames = { "ECO", "INTERACTIVE", "REALTIME" };
static const QStringList refreshRateProfileNames = { "ECO", "INTERACTIVE", "REALTIME", "CUSTOM" };
return refreshRateProfileNames;
}

View file

@ -127,6 +127,22 @@ public slots:
*/
void setRefreshRateProfile(RefreshRateProfile refreshRateProfile);
/*@jsdoc
* Sets a custom refresh rate.
* @function Performance.setCustomRefreshRate
* @param {RefreshRateRegime} refreshRateRegime - The refresh rate regime
* @param {int} value - The value for the regime
*/
void setCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime, int value);
/*@jsdoc
* Gets the value for a specific RefreshRateRegime.
* @function Performance.getCustomRefreshRate
* @param {RefreshRateRegime} - The regime to get the value from
* @returns {int} - The value from the specified regime
*/
int getCustomRefreshRate(RefreshRateManager::RefreshRateRegime regime) const;
/*@jsdoc
* Gets the current refresh rate profile in use.
* @function Performance.getRefreshRateProfile

View file

@ -21,6 +21,9 @@ SettingsScriptingInterface* SettingsScriptingInterface::getInstance() {
}
QVariant SettingsScriptingInterface::getValue(const QString& setting) {
if (_restrictPrivateValues && setting.startsWith(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/")) {
return {""};
}
QVariant value = Setting::Handle<QVariant>(setting).get();
if (!value.isValid()) {
value = "";
@ -29,6 +32,9 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting) {
}
QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVariant& defaultValue) {
if (_restrictPrivateValues && setting.startsWith(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/")) {
return {""};
}
QVariant value = Setting::Handle<QVariant>(setting, defaultValue).get();
if (!value.isValid()) {
value = "";
@ -40,7 +46,7 @@ void SettingsScriptingInterface::setValue(const QString& setting, const QVariant
if (getValue(setting) == value) {
return;
}
if (setting.startsWith("private/")) {
if (setting.startsWith("private/") || setting.startsWith(SETTINGS_FULL_PRIVATE_GROUP_NAME + "/")) {
if (_restrictPrivateValues) {
qWarning() << "SettingsScriptingInterface::setValue -- restricted write: " << setting << value;
return;

View file

@ -100,7 +100,8 @@ void setupPreferences() {
QStringList refreshRateProfiles
{ QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::ECO)),
QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::INTERACTIVE)),
QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::REALTIME)) };
QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::REALTIME)),
QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::CUSTOM)) };
preference->setItems(refreshRateProfiles);
preferences->addPreference(preference);

View file

@ -281,7 +281,7 @@ if (APPLE)
set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME})
set(DMG_SUBFOLDER_NAME "Vircadia")
set(DMG_SUBFOLDER_NAME "Overte")
set(ESCAPED_DMG_SUBFOLDER_NAME "")
set(DMG_SUBFOLDER_ICON "${CMAKE_SOURCE_DIR}/cmake/installer/install-folder.rsrc")

View file

@ -2106,6 +2106,14 @@ const QUrl& AvatarData::getSkeletonModelURL() const {
}
}
QString AvatarData::getSkeletonModelURLFromScript() const {
if (isMyAvatar() && !isMyAvatarURLProtected()) {
return _skeletonModelURL.toString();
}
return QString();
};
QByteArray AvatarData::packSkeletonData() const {
// Send an avatar trait packet with the skeleton data before the mesh is loaded
int avatarDataSize = 0;

View file

@ -610,6 +610,8 @@ public:
AvatarData();
virtual ~AvatarData();
virtual bool isMyAvatarURLProtected() const { return false; } // This needs to be here because both MyAvatar and AvatarData inherit from MyAvatar
static const QUrl& defaultFullAvatarModelUrl();
const QUuid getSessionUUID() const { return getID(); }
@ -1355,7 +1357,7 @@ public:
*/
Q_INVOKABLE virtual void detachAll(const QString& modelURL, const QString& jointName = QString());
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
QString getSkeletonModelURLFromScript() const;
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }

View file

@ -13,6 +13,7 @@
#include "ScriptAvatarData.h"
#include <NodeList.h>
#include <ScriptEngineCast.h>
#include <ScriptManager.h>
@ -204,7 +205,12 @@ bool ScriptAvatarData::getLookAtSnappingEnabled() const {
//
QString ScriptAvatarData::getSkeletonModelURLFromScript() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getSkeletonModelURLFromScript();
auto nodeList = DependencyManager::get<NodeList>();
if (sharedAvatarData->isMyAvatar() && !sharedAvatarData->isMyAvatarURLProtected() && nodeList->getThisNodeCanViewAssetURLs()) {
return sharedAvatarData->getSkeletonModelURLFromScript();
}
return QString();
} else {
return QString();
}

View file

@ -36,8 +36,7 @@ MaterialBaker::MaterialBaker(const QString& materialData, bool isURL, const QStr
_isURL(isURL),
_destinationPath(destinationPath),
_bakedOutputDir(bakedOutputDir),
_textureOutputDir(bakedOutputDir + "/materialTextures/" + QString::number(materialNum++)),
_scriptEngine(newScriptEngine())
_textureOutputDir(bakedOutputDir + "/materialTextures/" + QString::number(materialNum++))
{
}
@ -214,16 +213,20 @@ void MaterialBaker::outputMaterial() {
if (_materialResource->parsedMaterials.networkMaterials.size() == 1) {
auto networkMaterial = _materialResource->parsedMaterials.networkMaterials.begin();
auto scriptableMaterial = scriptable::ScriptableMaterial(networkMaterial->second);
QVariant materialVariant =
scriptable::scriptableMaterialToScriptValue(_scriptEngine.get(), scriptableMaterial).toVariant();
json.insert("materials", QJsonDocument::fromVariant(materialVariant).object());
_helperScriptEngine.run( [&] {
QVariant materialVariant =
scriptable::scriptableMaterialToScriptValue(_helperScriptEngine.get(), scriptableMaterial).toVariant();
json.insert("materials", QJsonDocument::fromVariant(materialVariant).object());
});
} else {
QJsonArray materialArray;
for (auto networkMaterial : _materialResource->parsedMaterials.networkMaterials) {
auto scriptableMaterial = scriptable::ScriptableMaterial(networkMaterial.second);
QVariant materialVariant =
scriptable::scriptableMaterialToScriptValue(_scriptEngine.get(), scriptableMaterial).toVariant();
materialArray.append(QJsonDocument::fromVariant(materialVariant).object());
_helperScriptEngine.run( [&] {
QVariant materialVariant =
scriptable::scriptableMaterialToScriptValue(_helperScriptEngine.get(), scriptableMaterial).toVariant();
materialArray.append(QJsonDocument::fromVariant(materialVariant).object());
});
}
json.insert("materials", materialArray);
}
@ -269,19 +272,32 @@ void MaterialBaker::setMaterials(const QHash<QString, hfm::Material>& materials,
_materialResource = NetworkMaterialResourcePointer(new NetworkMaterialResource(), [](NetworkMaterialResource* ptr) { ptr->deleteLater(); });
for (auto& material : materials) {
_materialResource->parsedMaterials.names.push_back(material.name.toStdString());
_materialResource->parsedMaterials.networkMaterials[material.name.toStdString()] = std::make_shared<NetworkMaterial>(material, baseURL);
if (!material.isMToonMaterial) {
_materialResource->parsedMaterials.networkMaterials[material.name.toStdString()] = std::make_shared<NetworkMaterial>(material, baseURL);
} else {
_materialResource->parsedMaterials.networkMaterials[material.name.toStdString()] = std::make_shared<NetworkMToonMaterial>(material, baseURL);
}
// Store any embedded texture content
addTexture(material.name, image::TextureUsage::NORMAL_TEXTURE, material.normalTexture);
addTexture(material.name, image::TextureUsage::ALBEDO_TEXTURE, material.albedoTexture);
addTexture(material.name, image::TextureUsage::GLOSS_TEXTURE, material.glossTexture);
addTexture(material.name, image::TextureUsage::ROUGHNESS_TEXTURE, material.roughnessTexture);
addTexture(material.name, image::TextureUsage::SPECULAR_TEXTURE, material.specularTexture);
addTexture(material.name, image::TextureUsage::METALLIC_TEXTURE, material.metallicTexture);
addTexture(material.name, image::TextureUsage::EMISSIVE_TEXTURE, material.emissiveTexture);
addTexture(material.name, image::TextureUsage::OCCLUSION_TEXTURE, material.occlusionTexture);
addTexture(material.name, image::TextureUsage::SCATTERING_TEXTURE, material.scatteringTexture);
addTexture(material.name, image::TextureUsage::LIGHTMAP_TEXTURE, material.lightmapTexture);
if (!material.isMToonMaterial) {
addTexture(material.name, image::TextureUsage::GLOSS_TEXTURE, material.glossTexture);
addTexture(material.name, image::TextureUsage::ROUGHNESS_TEXTURE, material.roughnessTexture);
addTexture(material.name, image::TextureUsage::SPECULAR_TEXTURE, material.specularTexture);
addTexture(material.name, image::TextureUsage::METALLIC_TEXTURE, material.metallicTexture);
addTexture(material.name, image::TextureUsage::OCCLUSION_TEXTURE, material.occlusionTexture);
addTexture(material.name, image::TextureUsage::SCATTERING_TEXTURE, material.scatteringTexture);
addTexture(material.name, image::TextureUsage::LIGHTMAP_TEXTURE, material.lightmapTexture);
} else {
addTexture(material.name, image::TextureUsage::ALBEDO_TEXTURE, material.shadeTexture);
addTexture(material.name, image::TextureUsage::ROUGHNESS_TEXTURE, material.shadingShiftTexture);
addTexture(material.name, image::TextureUsage::EMISSIVE_TEXTURE, material.matcapTexture);
addTexture(material.name, image::TextureUsage::ALBEDO_TEXTURE, material.rimTexture);
addTexture(material.name, image::TextureUsage::ROUGHNESS_TEXTURE, material.uvAnimationTexture);
}
}
}

View file

@ -21,6 +21,7 @@
#include "TextureBaker.h"
#include "baking/TextureFileNamer.h"
#include <HelperScriptEngine.h>
#include <procedural/ProceduralMaterialCache.h>
#include <ScriptEngine.h>
@ -72,7 +73,7 @@ private:
QString _textureOutputDir;
QString _bakedMaterialData;
ScriptEnginePointer _scriptEngine;
HelperScriptEngine _helperScriptEngine;
static std::function<QThread*()> _getNextOvenWorkerThreadOperator;
TextureFileNamer _textureFileNamer;

View file

@ -1195,9 +1195,9 @@ Mapping::Pointer UserInputMapper::parseMapping(const QString& json) {
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8(), &error);
// check validity of the document
if (doc.isNull()) {
qCDebug(controllers) << "Invalid JSON...\n";
qCDebug(controllers) << error.errorString();
qCDebug(controllers) << "JSON was:\n" << json << Qt::endl;
qCCritical(controllers) << "Invalid JSON...\n";
qCCritical(controllers) << error.errorString();
qCCritical(controllers) << "JSON was:\n" << json << Qt::endl;
return Mapping::Pointer();
}

View file

@ -743,6 +743,13 @@ void OpenGLDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
}
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
// Drop current frame after presenting it once.
// This is required for the OpenXR frame cycle, since we call xrEndFrame after presenting.
// xrEndFrame must not be called multiple times.
if (_presentOnlyOnce) {
_currentFrame.reset();
}
} else if (alwaysPresent()) {
refreshRateController->clockEndTime();
internalPresent();

View file

@ -201,4 +201,6 @@ protected:
QImage getScreenshot(float aspectRatio);
QImage getSecondaryCameraScreenshot();
bool _presentOnlyOnce = false;
};

View file

@ -56,16 +56,16 @@ QRect HmdDisplayPlugin::getRecommendedHUDRect() const {
return CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT;
}
glm::mat4 HmdDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
return _eyeOffsets[eye];
glm::mat4 HmdDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
return _eyeOffsets[eye];
}
glm::mat4 HmdDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& baseProjection) const {
return _eyeProjections[eye];
glm::mat4 HmdDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& baseProjection) const {
return _eyeProjections[eye];
}
glm::mat4 HmdDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const {
return _cullingProjection;
glm::mat4 HmdDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const {
return _cullingProjection;
}
glm::ivec4 HmdDisplayPlugin::eyeViewport(Eye eye) const {

View file

@ -337,21 +337,26 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
}
// Draw!
DependencyManager::get<GeometryCache>()->renderSphere(batch);
const uint32_t compactColor = 0xFFFFFFFF;
_colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*) &compactColor);
DependencyManager::get<GeometryCache>()->renderShape(batch, GeometryCache::Shape::Sphere, _colorBuffer);
} else {
auto proceduralDrawMaterial = std::static_pointer_cast<graphics::ProceduralMaterial>(drawMaterial);
glm::vec4 outColor = glm::vec4(drawMaterial->getAlbedo(), drawMaterial->getOpacity());
outColor = proceduralDrawMaterial->getColor(outColor);
proceduralDrawMaterial->prepare(batch, transform.getTranslation(), transform.getScale(),
transform.getRotation(), _created, ProceduralProgramKey(outColor.a < 1.0f));
const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor));
_colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*) &compactColor);
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
DependencyManager::get<GeometryCache>()->renderWireSphere(batch, outColor);
DependencyManager::get<GeometryCache>()->renderWireShape(batch, GeometryCache::Shape::Sphere, _colorBuffer);
} else {
DependencyManager::get<GeometryCache>()->renderSphere(batch, outColor);
DependencyManager::get<GeometryCache>()->renderShape(batch, GeometryCache::Shape::Sphere, _colorBuffer);
}
}
args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->getShapeTriangleCount(GeometryCache::Shape::Sphere);
}
void MaterialEntityRenderer::setCurrentMaterialName(const std::string& currentMaterialName) {

View file

@ -67,6 +67,7 @@ private:
std::shared_ptr<NetworkMaterial> _appliedMaterial;
std::string _currentMaterialName;
gpu::BufferPointer _colorBuffer { std::make_shared<gpu::Buffer>() };
};
} }

View file

@ -21,23 +21,48 @@ using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER = 0;
static gpu::Stream::FormatPointer _vertexFormat;
static std::weak_ptr<gpu::Pipeline> _texturedPipeline;
// forward, transparent, shadow, wireframe
static std::map<std::tuple<bool, bool, bool, bool>, gpu::PipelinePointer> _pipelines;
static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
auto texturedPipeline = _texturedPipeline.lock();
if (!texturedPipeline) {
auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, false, gpu::LESS_EQUAL);
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
PrepareStencil::testMask(*state);
if (_pipelines.empty()) {
using namespace shader::entities_renderer::program;
auto program = gpu::Shader::createProgram(shader::entities_renderer::program::textured_particle);
_texturedPipeline = texturedPipeline = gpu::Pipeline::create(program, state);
// forward, translucent, shadow
static const std::vector<std::tuple<bool, bool, bool, uint32_t>> keys = {
std::make_tuple(false, false, false, textured_particle),
std::make_tuple(true, false, false, textured_particle_forward),
std::make_tuple(false, true, false, textured_particle_translucent),
std::make_tuple(true, true, false, textured_particle_translucent_forward),
std::make_tuple(false, false, true, textured_particle_shadow),
// no such thing as shadow and forward/translucent
};
for (auto& key : keys) {
for (int i = 0; i < 2; ++i) {
bool transparent = std::get<1>(key);
bool wireframe = i == 0;
auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_BACK);
if (wireframe) {
state->setFillMode(gpu::State::FILL_LINE);
}
state->setDepthTest(true, !transparent, gpu::LESS_EQUAL);
state->setBlendFunction(transparent, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
transparent ? PrepareStencil::testMask(*state) : PrepareStencil::testMaskDrawShape(*state);
auto program = gpu::Shader::createProgram(std::get<3>(key));
_pipelines[std::make_tuple(std::get<0>(key), transparent, std::get<2>(key), wireframe)] = gpu::Pipeline::create(program, state);
}
}
}
return std::make_shared<render::ShapePipeline>(texturedPipeline, nullptr, nullptr, nullptr);
return std::make_shared<render::ShapePipeline>(_pipelines[std::make_tuple(args->_renderMethod == Args::RenderMethod::FORWARD, key.isTranslucent(),
args->_renderMode == Args::RenderMode::SHADOW_RENDER_MODE, key.isWireframe())], nullptr, nullptr, nullptr);
}
struct GpuParticle {
@ -138,26 +163,25 @@ void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEn
_uniformBuffer.edit<ParticleUniforms>() = particleUniforms;
}
ItemKey ParticleEffectEntityRenderer::getKey() {
// FIXME: implement isTransparent() for particles and an opaque pipeline
auto builder = ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
if (!_visible) {
builder.withInvisible();
}
if (_cullWithParent) {
builder.withSubMetaCulled();
}
return builder.build();
bool ParticleEffectEntityRenderer::isTransparent() const {
bool particleTransparent = _particleProperties.getColorStart().a < 1.0f || _particleProperties.getColorMiddle().a < 1.0f ||
_particleProperties.getColorFinish().a < 1.0f || _particleProperties.getColorSpread().a > 0.0f ||
_pulseProperties.getAlphaMode() != PulseMode::NONE || (_textureLoaded && _networkTexture && _networkTexture->getGPUTexture() &&
_networkTexture->getGPUTexture()->getUsage().isAlpha() && !_networkTexture->getGPUTexture()->getUsage().isAlphaMask());
return particleTransparent || Parent::isTransparent();
}
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER).withTranslucent();
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
if (isTransparent()) {
builder.withTranslucent();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
return builder.build();
}

View file

@ -28,7 +28,7 @@ protected:
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual ItemKey getKey() override;
bool isTransparent() const override;
virtual ShapeKey getShapeKey() override;
virtual Item::Bound getBound(RenderArgs* args) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -1719,21 +1719,28 @@ using namespace render;
using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER;
static std::map<std::tuple<bool, bool, bool>, ShapePipelinePointer> _pipelines;
// forward, shadow, fade, wireframe
static std::map<std::tuple<bool, bool, bool, bool>, ShapePipelinePointer> _pipelines;
static gpu::Stream::FormatPointer _vertexFormat;
ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
// FIXME: custom pipelines like this don't handle shadows or renderLayers correctly
if (_pipelines.empty()) {
using namespace shader::entities_renderer::program;
static const std::vector<std::tuple<bool, bool, uint32_t>> keys = {
std::make_tuple(false, false, polyvox), std::make_tuple(true, false, polyvox_forward)
// forward, shadow, fade
static const std::vector<std::tuple<bool, bool, bool, uint32_t>> keys = {
std::make_tuple(false, false, false, polyvox),
std::make_tuple(true, false, false, polyvox_forward),
std::make_tuple(false, true, false, polyvox_shadow),
// no such thing as forward + shadow
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
, std::make_tuple(false, true, polyvox_fade), std::make_tuple(true, true, polyvox_forward_fade)
std::make_tuple(false, false, true, polyvox_fade),
std::make_tuple(false, true, true, polyvox_shadow_fade),
// no such thing as forward + fade/shadow
#else
, std::make_tuple(false, true, polyvox), std::make_tuple(true, true, polyvox_forward)
std::make_tuple(false, false, true, polyvox),
std::make_tuple(false, true, true, polyvox_shadow),
// no such thing as forward + fade/shadow
#endif
};
for (auto& key : keys) {
@ -1749,19 +1756,19 @@ ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const Sha
state->setFillMode(gpu::State::FILL_LINE);
}
auto pipeline = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<2>(key)), state);
if (std::get<1>(key)) {
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr, nullptr, nullptr);
auto pipeline = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<3>(key)), state);
if (!std::get<2>(key)) {
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), std::get<2>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr, nullptr, nullptr);
} else {
const auto& fadeEffect = DependencyManager::get<FadeEffect>();
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr,
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), std::get<2>(key), wireframe)] = std::make_shared<render::ShapePipeline>(pipeline, nullptr,
fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
}
}
}
}
return _pipelines[std::make_tuple(args->_renderMethod == Args::RenderMethod::FORWARD, key.isFaded(), key.isWireframe())];
return _pipelines[std::make_tuple(args->_renderMethod == Args::RenderMethod::FORWARD, args->_renderMode == Args::RenderMode::SHADOW_RENDER_MODE, key.isFaded(), key.isWireframe())];
}
PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
@ -1775,16 +1782,6 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) :
_params = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
}
ItemKey PolyVoxEntityRenderer::getKey() {
auto builder = ItemKey::Builder::opaqueShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
if (_cullWithParent) {
builder.withSubMetaCulled();
}
return builder.build();
}
ShapeKey PolyVoxEntityRenderer::getShapeKey() {
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
if (_primitiveMode == PrimitiveMode::LINES) {
@ -1866,13 +1863,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
batch.setModelTransform(transform);
batch.setInputFormat(_vertexFormat);
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0,
sizeof(PolyVox::PositionMaterialNormal));
// TODO -- should we be setting this?
// batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer,
// 12,
// sizeof(PolyVox::PositionMaterialNormal));
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0, sizeof(PolyVox::PositionMaterialNormal));
batch.setIndexBuffer(gpu::UINT32, _mesh->getIndexBuffer()._buffer, 0);
for (size_t i = 0; i < _xyzTextures.size(); ++i) {

View file

@ -203,7 +203,6 @@ public:
}
protected:
virtual ItemKey getKey() override;
virtual ShapeKey getShapeKey() override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;

View file

@ -131,10 +131,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(outColor.a < 1.0f));
});
const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor));
_colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*) &compactColor);
if (wireframe) {
geometryCache->renderWireShape(batch, geometryShape, outColor);
geometryCache->renderWireShape(batch, geometryShape, _colorBuffer);
} else {
geometryCache->renderShape(batch, geometryShape, outColor);
geometryCache->renderShape(batch, geometryShape, _colorBuffer);
}
} else if (pipelineType == Pipeline::SIMPLE) {
// FIXME, support instanced multi-shape rendering using multidraw indirect
@ -149,10 +151,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
}
} else {
const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor));
_colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*) &compactColor);
if (wireframe) {
geometryCache->renderWireShape(batch, geometryShape, outColor);
geometryCache->renderWireShape(batch, geometryShape, _colorBuffer);
} else {
geometryCache->renderShape(batch, geometryShape, outColor);
geometryCache->renderShape(batch, geometryShape, _colorBuffer);
}
}
} else {
@ -160,7 +164,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
args->_details._materialSwitches++;
}
geometryCache->renderShape(batch, geometryShape);
const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor));
_colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*) &compactColor);
geometryCache->renderShape(batch, geometryShape, _colorBuffer);
}
const auto triCount = geometryCache->getShapeTriangleCount(geometryShape);

View file

@ -42,6 +42,8 @@ private:
std::shared_ptr<graphics::ProceduralMaterial> _material { std::make_shared<graphics::ProceduralMaterial>() };
glm::vec3 _color { NAN };
float _alpha { NAN };
gpu::BufferPointer _colorBuffer { std::make_shared<gpu::Buffer>() };
};
} }

View file

@ -0,0 +1 @@
DEFINES (translucent:f forward:f)/shadow:f

View file

@ -15,8 +15,34 @@ LAYOUT(binding=0) uniform sampler2D colorMap;
layout(location=0) in vec4 varColor;
layout(location=1) in vec2 varTexcoord;
layout(location=0) out vec4 outFragColor;
<@if HIFI_USE_FORWARD or HIFI_USE_SHADOW@>
layout(location=0) out vec4 _fragColor0;
<@else@>
<@include DeferredBufferWrite.slh@>
<@endif@>
void main(void) {
outFragColor = texture(colorMap, varTexcoord.xy) * varColor;
vec4 albedo = texture(colorMap, varTexcoord.xy) * varColor;
<@if HIFI_USE_FORWARD or HIFI_USE_SHADOW@>
<@if not HIFI_USE_TRANSLUCENT@>
// to reduce texel flickering for floating point error we discard when alpha is "almost one"
if (albedo.a < 0.999999) {
discard;
}
<@endif@>
<@if HIFI_USE_FORWARD@>
_fragColor0 = albedo;
<@else@>
_fragColor0 = vec4(1.0);
<@endif@>
<@else@>
vec3 NORMAL = vec3(1.0, 0.0, 0.0);
<@if not HIFI_USE_TRANSLUCENT@>
packDeferredFragmentUnlit(NORMAL, albedo.a, albedo.rgb);
<@else@>
packDeferredFragmentTranslucent(NORMAL, albedo.a, albedo.rgb, DEFAULT_ROUGHNESS);
<@endif@>
<@endif@>
}

View file

@ -22,10 +22,12 @@
const float AmbientLightPropertyGroup::DEFAULT_AMBIENT_LIGHT_INTENSITY = 0.5f;
void AmbientLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
auto nodeList = DependencyManager::get<NodeList>();
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_LIGHT_INTENSITY, AmbientLight, ambientLight, AmbientIntensity, ambientIntensity);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_LIGHT_URL, AmbientLight, ambientLight, AmbientURL, ambientURL);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_AMBIENT_LIGHT_URL, AmbientLight, ambientLight, AmbientURL, ambientURL);
}
void AmbientLightPropertyGroup::copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) {

View file

@ -43,7 +43,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const AmbientLightPropertyGroup& other);

View file

@ -68,8 +68,10 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
* maintained when the animation stops playing, <code>false</code> if they aren't.
*/
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
auto nodeList = DependencyManager::get<NodeList>();
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_ANIMATION_URL, Animation, animation, URL, url);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame);

View file

@ -37,7 +37,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const AnimationPropertyGroup& other);

View file

@ -19,7 +19,8 @@
#include "EntityItemPropertiesMacros.h"
void BloomPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_BLOOM_INTENSITY, Bloom, bloom, BloomIntensity, bloomIntensity);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_BLOOM_THRESHOLD, Bloom, bloom, BloomThreshold, bloomThreshold);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_BLOOM_SIZE, Bloom, bloom, BloomSize, bloomSize);

View file

@ -44,7 +44,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const BloomPropertyGroup& other);

View file

@ -33,6 +33,7 @@
#include <Extents.h>
#include <VariantMapToScriptValue.h>
#include <ScriptValue.h>
#include <PhysicsHelpers.h>
#include "EntitiesLogging.h"
#include "EntityItem.h"
@ -1566,6 +1567,8 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
return properties;
}
auto nodeList = DependencyManager::get<NodeList>();
bool isMyOwnAvatarEntity = _entityHostType == entity::HostType::AVATAR && (_owningAvatarID == AVATAR_SELF_ID || _owningAvatarID == Physics::getSessionUUID());
if (_idSet && (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::ID))) {
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString());
}
@ -1615,7 +1618,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IGNORE_PICK_INTERSECTION, ignorePickIntersection);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RENDER_WITH_ZONES, renderWithZones);
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BILLBOARD_MODE, billboardMode, getBillboardModeAsString());
_grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
// Physics
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DENSITY, density);
@ -1634,7 +1637,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISION_MASK, collisionMask, collidesWith, getCollisionMaskAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DYNAMIC, dynamic);
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_DYNAMIC, dynamic, collisionsWillMove, getDynamic()); // legacy support
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_COLLISION_SOUND_URL, collisionSoundURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACTION_DATA, actionData);
// Cloning
@ -1660,10 +1663,10 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Particles only
if (_type == EntityTypes::ParticleEffect) {
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAX_PARTICLES, maxParticles);
@ -1710,11 +1713,11 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Models only
if (_type == EntityTypes::Model) {
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_MODEL_URL, modelURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_SCALE, modelScale);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
@ -1724,7 +1727,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GROUP_CULLED, groupCulled);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_BLENDSHAPE_COEFFICIENTS, blendshapeCoefficients);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USE_ORIGINAL_PIVOT, useOriginalPivot);
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
}
// FIXME: Shouldn't provide a shapeType property for Box and Sphere entities.
@ -1738,7 +1741,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
if (_type == EntityTypes::Box || _type == EntityTypes::Sphere || _type == EntityTypes::Shape) {
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHAPE, shape);
}
@ -1754,7 +1757,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Text only
if (_type == EntityTypes::Text) {
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT, text);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_HEIGHT, lineHeight);
@ -1777,17 +1780,17 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Zones only
if (_type == EntityTypes::Zone) {
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
_keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
_ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_FILTER_URL, filterURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_KEY_LIGHT_MODE, keyLightMode, getKeyLightModeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_LIGHT_MODE, ambientLightMode, getAmbientLightModeAsString());
@ -1802,11 +1805,11 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
if (_type == EntityTypes::Web) {
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SOURCE_URL, sourceUrl);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_SOURCE_URL, sourceUrl);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DPI, dpi);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT_URL, scriptURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_SCRIPT_URL, scriptURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAX_FPS, maxFPS);
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_INPUT_MODE, inputMode, getInputModeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, showKeyboardFocusHighlight);
@ -1819,9 +1822,9 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_DATA, voxelData);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_TEXTURE_URL, xTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_TEXTURE_URL, yTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_TEXTURE_URL, zTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_X_TEXTURE_URL, xTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_Y_TEXTURE_URL, yTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_Z_TEXTURE_URL, zTextureURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_N_NEIGHBOR_ID, xNNeighborID);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_N_NEIGHBOR_ID, yNNeighborID);
@ -1855,14 +1858,14 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Materials
if (_type == EntityTypes::Material) {
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_URL, materialURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_MATERIAL_URL, materialURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_MATERIAL_MAPPING_MODE, materialMappingMode, getMaterialMappingModeAsString());
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_PRIORITY, priority);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_MATERIAL_NAME, parentMaterialName);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_POS, materialMappingPos);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_DATA, materialData);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_MATERIAL_DATA, materialData);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_REPEAT, materialRepeat);
}
@ -1870,15 +1873,16 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
if (_type == EntityTypes::Image) {
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IMAGE_URL, imageURL);
COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_IMAGE_URL, imageURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMISSIVE, emissive);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEEP_ASPECT_RATIO, keepAspectRatio);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SUB_IMAGE, subImage);
// Handle conversions to old 'textures' property from "imageURL"
if (((!returnNothingOnEmptyPropertyFlags && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(PROP_IMAGE_URL)) &&
if ((isMyOwnAvatarEntity || nodeList->getThisNodeCanViewAssetURLs()) &&
((!returnNothingOnEmptyPropertyFlags && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(PROP_IMAGE_URL)) &&
(!skipDefaults || defaultEntityProperties._imageURL != _imageURL)) {
ScriptValue textures = engine->newObject();
textures.setProperty("tex.picture", _imageURL);
@ -1890,7 +1894,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
if (_type == EntityTypes::Grid) {
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GRID_FOLLOW_CAMERA, followCamera);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAJOR_GRID_EVERY, majorGridEvery);
@ -1900,7 +1904,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
// Gizmo only
if (_type == EntityTypes::Gizmo) {
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_GIZMO_TYPE, gizmoType, getGizmoTypeAsString());
_ring.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags);
_ring.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
}
/*@jsdoc
@ -2549,7 +2553,7 @@ bool EntityItemProperties::entityPropertyFlagsFromScriptValue(const ScriptValue&
if (object.isString()) {
EntityPropertyInfo propertyInfo;
if (getPropertyInfo(object.toString(), propertyInfo)) {
flags << propertyInfo.propertyEnum;
flags << propertyInfo.propertyEnums;
}
}
else if (object.isArray()) {
@ -2558,7 +2562,7 @@ bool EntityItemProperties::entityPropertyFlagsFromScriptValue(const ScriptValue&
QString propertyName = object.property(i).toString();
EntityPropertyInfo propertyInfo;
if (getPropertyInfo(propertyName, propertyInfo)) {
flags << propertyInfo.propertyEnum;
flags << propertyInfo.propertyEnums;
}
}
}
@ -2794,7 +2798,7 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
{ // Keylight
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color);
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity);
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLight, keylight, Direction, direction);
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction);
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows);
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_BIAS, KeyLight, keyLight, ShadowBias, shadowBias, 0.0f, 1.0f);
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance, 1.0f, 250.0f);
@ -2943,14 +2947,14 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
*/
ScriptValue EntityPropertyInfoToScriptValue(ScriptEngine* engine, const EntityPropertyInfo& propertyInfo) {
ScriptValue obj = engine->newObject();
obj.setProperty("propertyEnum", propertyInfo.propertyEnum);
obj.setProperty("propertyEnum", propertyInfo.propertyEnums.firstFlag());
obj.setProperty("minimum", propertyInfo.minimum.toString());
obj.setProperty("maximum", propertyInfo.maximum.toString());
return obj;
}
bool EntityPropertyInfoFromScriptValue(const ScriptValue& object, EntityPropertyInfo& propertyInfo) {
propertyInfo.propertyEnum = (EntityPropertyList)object.property("propertyEnum").toVariant().toUInt();
propertyInfo.propertyEnums = (EntityPropertyList)object.property("propertyEnum").toVariant().toUInt();
propertyInfo.minimum = object.property("minimum").toVariant();
propertyInfo.maximum = object.property("maximum").toVariant();
return true;

View file

@ -80,11 +80,11 @@ using u8vec3Color = glm::u8vec3;
struct EntityPropertyInfo {
EntityPropertyInfo(EntityPropertyList propEnum) :
propertyEnum(propEnum) {}
propertyEnums(propEnum) {}
EntityPropertyInfo(EntityPropertyList propEnum, QVariant min, QVariant max) :
propertyEnum(propEnum), minimum(min), maximum(max) {}
propertyEnums(propEnum), minimum(min), maximum(max) {}
EntityPropertyInfo() = default;
EntityPropertyList propertyEnum;
EntityPropertyFlags propertyEnums;
QVariant minimum;
QVariant maximum;
};

View file

@ -218,6 +218,37 @@ inline ScriptValue convertScriptValue(ScriptEngine* e, const AACube& v) { return
properties.setProperty(#P, V); \
}
#define COPY_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(p, P) \
if (((!returnNothingOnEmptyPropertyFlags && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
if (isMyOwnAvatarEntity || nodeList->getThisNodeCanViewAssetURLs()) { \
ScriptValue V = convertScriptValue(engine, _##P); \
properties.setProperty(#P, V); \
} else { \
const QString emptyURL = ""; \
ScriptValue V = convertScriptValue(engine, emptyURL); \
properties.setProperty(#P, V); \
} \
}
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(X, G, g, P, p) \
if (((!returnNothingOnEmptyPropertyFlags && desiredProperties.isEmpty()) || desiredProperties.getHasProperty(X)) && \
(!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \
if (isMyOwnAvatarEntity || nodeList->getThisNodeCanViewAssetURLs()) { \
ScriptValue groupProperties = properties.property(#g); \
if (!groupProperties.isValid()) { \
groupProperties = engine->newObject(); \
} \
ScriptValue V = convertScriptValue(engine, get##P()); \
groupProperties.setProperty(#p, V); \
properties.setProperty(#g, groupProperties); \
} else { \
const QString emptyURL = ""; \
ScriptValue V = convertScriptValue(engine, emptyURL); \
properties.setProperty(#P, V); \
} \
}
typedef QVector<glm::vec3> qVectorVec3;
typedef QVector<glm::quat> qVectorQuat;
typedef QVector<bool> qVectorBool;
@ -459,14 +490,16 @@ inline QRect QRect_convertFromScriptValue(const ScriptValue& v, bool& isValid) {
{ \
EntityPropertyInfo propertyInfo = EntityPropertyInfo(P); \
_propertyInfos[#g "." #n] = propertyInfo; \
_enumsToPropertyStrings[P] = #g "." #n; \
_propertyInfos[#g].propertyEnums << P; \
_enumsToPropertyStrings[P] = #g "." #n; \
}
#define ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(P, G, g, N, n, M, X) \
{ \
EntityPropertyInfo propertyInfo = EntityPropertyInfo(P, M, X); \
_propertyInfos[#g "." #n] = propertyInfo; \
_enumsToPropertyStrings[P] = #g "." #n; \
_propertyInfos[#g].propertyEnums << P; \
_enumsToPropertyStrings[P] = #g "." #n; \
}
#define DEFINE_CORE(N, n, T, V) \

View file

@ -97,6 +97,7 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
connect(nodeList.data(), &NodeList::canGetAndSetPrivateUserDataChanged, this, &EntityScriptingInterface::canGetAndSetPrivateUserDataChanged);
connect(nodeList.data(), &NodeList::canRezAvatarEntitiesChanged, this, &EntityScriptingInterface::canRezAvatarEntitiesChanged);
connect(nodeList.data(), &NodeList::canViewAssetURLsChanged, this, &EntityScriptingInterface::canViewAssetURLsChanged);
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::EntityScriptCallMethod,
@ -291,6 +292,11 @@ bool EntityScriptingInterface::canRezAvatarEntities() {
return nodeList->getThisNodeCanRezAvatarEntities();
}
bool EntityScriptingInterface::canViewAssetURLs() {
auto nodeList = DependencyManager::get<NodeList>();
return nodeList->getThisNodeCanViewAssetURLs();
}
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
if (_entityTree) {
disconnect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity);

View file

@ -288,6 +288,14 @@ public slots:
*/
Q_INVOKABLE bool canRezAvatarEntities();
/*@jsdoc
* Checks whether or not the script can view asset URLs
* @function Entities.canViewAssetURLs
* @returns {boolean} <code>true</code> if the domain server will allow the script to view asset URLs,
* otherwise <code>false</code>.
*/
Q_INVOKABLE bool canViewAssetURLs();
/*@jsdoc
* <p>How an entity is hosted and sent to others for display.</p>
* <table>
@ -2249,6 +2257,14 @@ signals:
*/
void canRezAvatarEntitiesChanged(bool canRezAvatarEntities);
/*@jsdoc
* Triggered when your ability to view asset URLs is changed.
* @function Entities.canViewAssetURLsChanged
* @param {boolean} canViewAssetURLs - <code>true</code> if the script can view asset URLs,
* <code>false</code> if it can't.
* @returns {Signal}
*/
void canViewAssetURLsChanged(bool canViewAssetURLs);
/*@jsdoc
* Triggered when a mouse button is clicked while the mouse cursor is on an entity, or a controller trigger is fully

View file

@ -2553,11 +2553,10 @@ bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer
}
entityDescription["DataVersion"] = _persistDataVersion;
entityDescription["Id"] = _persistID;
const std::lock_guard<std::mutex> scriptLock(scriptEngineMutex);
RecurseOctreeToMapOperator theOperator(entityDescription, element, scriptEngine.get(), skipDefaultValues,
skipThoseWithBadParents, _myAvatar);
withReadLock([&] {
recurseTreeWithOperator(&theOperator);
_helperScriptEngine.run( [&] {
RecurseOctreeToMapOperator theOperator(entityDescription, element, _helperScriptEngine.get(), skipDefaultValues,
skipThoseWithBadParents, _myAvatar);
withReadLock([&] { recurseTreeWithOperator(&theOperator); });
});
return true;
}
@ -2728,11 +2727,10 @@ bool EntityTree::readFromMap(QVariantMap& map, const bool isImport) {
}
EntityItemProperties properties;
{
const std::lock_guard<std::mutex> scriptLock(scriptEngineMutex);
ScriptValue entityScriptValue = variantMapToScriptValue(entityMap, *scriptEngine);
_helperScriptEngine.run( [&] {
ScriptValue entityScriptValue = variantMapToScriptValue(entityMap, *_helperScriptEngine.get());
EntityItemPropertiesFromScriptValueIgnoreReadOnly(entityScriptValue, properties);
}
});
EntityItemID entityItemID;
if (entityMap.contains("id")) {
@ -2881,13 +2879,12 @@ bool EntityTree::readFromMap(QVariantMap& map, const bool isImport) {
}
bool EntityTree::writeToJSON(QString& jsonString, const OctreeElementPointer& element) {
const std::lock_guard<std::mutex> scriptLock(scriptEngineMutex);
RecurseOctreeToJSONOperator theOperator(element, scriptEngine.get(), jsonString);
withReadLock([&] {
recurseTreeWithOperator(&theOperator);
});
_helperScriptEngine.run( [&] {
RecurseOctreeToJSONOperator theOperator(element, _helperScriptEngine.get(), jsonString);
withReadLock([&] { recurseTreeWithOperator(&theOperator); });
jsonString = theOperator.getJson();
jsonString = theOperator.getJson();
});
return true;
}

View file

@ -15,6 +15,7 @@
#include <QSet>
#include <QVector>
#include <HelperScriptEngine.h>
#include <Octree.h>
#include <SpatialParentFinder.h>
@ -387,8 +388,7 @@ private:
MovingEntitiesOperator& moveOperator, bool force, bool tellServer);
// Script engine for writing entity tree data to and from JSON
std::mutex scriptEngineMutex;
ScriptEnginePointer scriptEngine{ newScriptEngine() };
HelperScriptEngine _helperScriptEngine;
};
void convertGrabUserDataToProperties(EntityItemProperties& properties);

View file

@ -20,7 +20,9 @@
void GrabPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
auto nodeList = DependencyManager::get<NodeList>();
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController);
@ -36,7 +38,7 @@ void GrabPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProp
EquippableRightPosition, equippableRightPosition);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
EquippableRightRotation, equippableRightRotation);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab,
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab,
EquippableIndicatorURL, equippableIndicatorURL);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab,
EquippableIndicatorScale, equippableIndicatorScale);

View file

@ -75,7 +75,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const GrabPropertyGroup& other);

View file

@ -19,7 +19,8 @@
#include "EntityItemPropertiesMacros.h"
void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor, u8vec3Color);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor, u8vec3Color);

View file

@ -80,7 +80,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const HazePropertyGroup& other);

View file

@ -28,7 +28,8 @@ const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_SHADOW_BIAS { 0.5f };
const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_SHADOW_MAX_DISTANCE { 40.0f };
void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color, u8vec3Color);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity);

View file

@ -50,7 +50,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const KeyLightPropertyGroup& other);

View file

@ -34,7 +34,8 @@ public:
virtual ~PropertyGroup() = default;
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const = 0;
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags, bool isMyOwnAvatarEntity) const = 0;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) = 0;
virtual void debugDump() const { }
virtual void listChangedProperties(QList<QString>& out) { }

View file

@ -60,8 +60,9 @@ void PulsePropertyGroup::setAlphaModeFromString(const QString& pulseMode) {
}
void PulsePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_MIN, Pulse, pulse, Min, min);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_MAX, Pulse, pulse, Max, max);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_PERIOD, Pulse, pulse, Period, period);

View file

@ -44,7 +44,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const PulsePropertyGroup& other);

View file

@ -23,8 +23,9 @@ const float RingGizmoPropertyGroup::MIN_RADIUS = 0.0f;
const float RingGizmoPropertyGroup::MAX_RADIUS = 0.5f;
void RingGizmoPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_START_ANGLE, Ring, ring, StartAngle, startAngle);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_END_ANGLE, Ring, ring, EndAngle, endAngle);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_INNER_RADIUS, Ring, ring, InnerRadius, innerRadius);

View file

@ -60,7 +60,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const RingGizmoPropertyGroup& other);

View file

@ -20,9 +20,11 @@
const glm::u8vec3 SkyboxPropertyGroup::DEFAULT_COLOR = { 0, 0, 0 };
void SkyboxPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const {
void SkyboxPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags, bool isMyOwnAvatarEntity) const {
auto nodeList = DependencyManager::get<NodeList>();
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color, u8vec3Color);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_IF_URL_PERMISSION(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
}
void SkyboxPropertyGroup::copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) {

View file

@ -43,7 +43,8 @@ public:
// EntityItemProperty related helpers
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
ScriptEngine* engine, bool skipDefaults,
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags) const override;
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
bool isMyOwnAvatarEntity) const override;
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
void merge(const SkyboxPropertyGroup& other);

View file

@ -100,8 +100,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_glUniformMatrix3fv),
(&::gpu::gl::GLBackend::do_glUniformMatrix4fv),
(&::gpu::gl::GLBackend::do_glColor4f),
(&::gpu::gl::GLBackend::do_pushProfileRange),
(&::gpu::gl::GLBackend::do_popProfileRange),
};
@ -838,22 +836,6 @@ void GLBackend::do_glUniformMatrix4fv(const Batch& batch, size_t paramOffset) {
(void)CHECK_GL_ERROR();
}
void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) {
glm::vec4 newColor(
batch._params[paramOffset + 3]._float,
batch._params[paramOffset + 2]._float,
batch._params[paramOffset + 1]._float,
batch._params[paramOffset + 0]._float);
if (_input._colorAttribute != newColor) {
_input._colorAttribute = newColor;
glVertexAttrib4fv(gpu::Stream::COLOR, &_input._colorAttribute.r);
_input._hasColorAttribute = true;
}
(void)CHECK_GL_ERROR();
}
void GLBackend::releaseBuffer(GLuint id, Size size) const {
Lock lock(_trashMutex);
_currentFrameTrash.buffersTrash.push_back({ id, size });

View file

@ -241,8 +241,6 @@ public:
virtual void do_glUniformMatrix3fv(const Batch& batch, size_t paramOffset) final;
virtual void do_glUniformMatrix4fv(const Batch& batch, size_t paramOffset) final;
virtual void do_glColor4f(const Batch& batch, size_t paramOffset) final;
// The State setters called by the GLState::Commands when a new state is assigned
virtual void do_setStateFillMode(int32 mode) final;
virtual void do_setStateCullMode(int32 mode) final;
@ -350,8 +348,6 @@ protected:
struct InputStageState {
bool _invalidFormat { true };
bool _lastUpdateStereoState { false };
bool _hasColorAttribute { false };
bool _hadColorAttribute { false };
FormatReference _format { GPU_REFERENCE_INIT_VALUE };
std::string _formatKey;
@ -368,8 +364,6 @@ protected:
std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferStrides;
std::array<GLuint, MAX_NUM_INPUT_BUFFERS> _bufferVBOs;
glm::vec4 _colorAttribute { 1.0f };
BufferReference _indexBuffer;
Offset _indexBufferOffset { 0 };
Type _indexBufferType { UINT32 };

View file

@ -103,9 +103,6 @@ void GLBackend::resetInputStage() {
reset(_input._format);
_input._formatKey.clear();
_input._invalidFormat = false;
_input._hasColorAttribute = false;
_input._hadColorAttribute = false;
_input._colorAttribute = vec4(1.0f);
_input._attributeActivation.reset();
for (uint32_t i = 0; i < _input._buffers.size(); i++) {
@ -163,8 +160,6 @@ void GLBackend::updateInput() {
#endif
_input._lastUpdateStereoState = isStereoNow;
bool hasColorAttribute = _input._hasColorAttribute;
if (_input._invalidFormat) {
InputStageState::ActivationCache newActivation;
@ -194,8 +189,6 @@ void GLBackend::updateInput() {
GLenum perLocationSize = attrib._element.getLocationSize();
hasColorAttribute |= slot == Stream::COLOR;
for (GLuint locNum = 0; locNum < locationCount; ++locNum) {
GLuint attriNum = (GLuint)(slot + locNum);
newActivation.set(attriNum);
@ -226,12 +219,6 @@ void GLBackend::updateInput() {
glVertexBindingDivisor(bufferChannelNum, frequency);
#endif
}
if (!hasColorAttribute && _input._hadColorAttribute) {
// The previous input stage had a color attribute but this one doesn't, so reset the color to pure white.
_input._colorAttribute = glm::vec4(1.0f);
glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r);
}
}
// Manage Activation what was and what is expected now
@ -253,9 +240,6 @@ void GLBackend::updateInput() {
_stats._ISNumFormatChanges++;
}
_input._hadColorAttribute = hasColorAttribute;
_input._hasColorAttribute = false;
if (_input._invalidBuffers.any()) {
auto vbo = _input._bufferVBOs.data();
auto offset = _input._bufferOffsets.data();

View file

@ -33,8 +33,6 @@ void GL41Backend::updateInput() {
#endif
_input._lastUpdateStereoState = isStereoNow;
bool hasColorAttribute = _input._hasColorAttribute;
if (_input._invalidFormat || _input._invalidBuffers.any()) {
auto format = acquire(_input._format);
@ -110,8 +108,6 @@ void GL41Backend::updateInput() {
uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]);
GLboolean isNormalized = attrib._element.isNormalized();
hasColorAttribute |= slot == Stream::COLOR;
for (size_t locNum = 0; locNum < locationCount; ++locNum) {
if (attrib._element.isInteger()) {
glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride,
@ -131,17 +127,8 @@ void GL41Backend::updateInput() {
}
}
}
if (!hasColorAttribute && _input._hadColorAttribute) {
// The previous input stage had a color attribute but this one doesn't, so reset the color to pure white.
_input._colorAttribute = glm::vec4(1.0f);
glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r);
}
}
// everything format related should be in sync now
_input._invalidFormat = false;
}
_input._hadColorAttribute = hasColorAttribute;
_input._hasColorAttribute = false;
}

View file

@ -35,8 +35,6 @@ void GL45Backend::updateInput() {
#endif
_input._lastUpdateStereoState = isStereoNow;
bool hasColorAttribute = _input._hasColorAttribute;
if (_input._invalidFormat) {
InputStageState::ActivationCache newActivation;
@ -66,8 +64,6 @@ void GL45Backend::updateInput() {
GLenum perLocationSize = attrib._element.getLocationSize();
hasColorAttribute |= slot == Stream::COLOR;
for (GLuint locNum = 0; locNum < locationCount; ++locNum) {
GLuint attriNum = (GLuint)(slot + locNum);
newActivation.set(attriNum);
@ -98,12 +94,6 @@ void GL45Backend::updateInput() {
glVertexBindingDivisor(bufferChannelNum, frequency);
#endif
}
if (!hasColorAttribute && _input._hadColorAttribute) {
// The previous input stage had a color attribute but this one doesn't, so reset the color to pure white.
_input._colorAttribute = glm::vec4(1.0f);
glVertexAttrib4fv(Stream::COLOR, &_input._colorAttribute.r);
}
}
// Manage Activation what was and what is expected now
@ -125,9 +115,6 @@ void GL45Backend::updateInput() {
_stats._ISNumFormatChanges++;
}
_input._hadColorAttribute = hasColorAttribute;
_input._hasColorAttribute = false;
if (_input._invalidBuffers.any()) {
auto vbo = _input._bufferVBOs.data();
auto offset = _input._bufferOffsets.data();

View file

@ -687,15 +687,6 @@ void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, cons
_params.emplace_back(location);
}
void Batch::_glColor4f(float red, float green, float blue, float alpha) {
ADD_COMMAND(glColor4f);
_params.emplace_back(alpha);
_params.emplace_back(blue);
_params.emplace_back(green);
_params.emplace_back(red);
}
void Batch::finishFrame(BufferUpdates& updates) {
PROFILE_RANGE(render_gpu, __FUNCTION__);

View file

@ -30,11 +30,11 @@ class QDebug;
#define BATCH_PREALLOCATE_MIN 128
namespace gpu {
// The named batch data provides a mechanism for accumulating data into buffers over the course
// of many independent calls. For instance, two objects in the scene might both want to render
// The named batch data provides a mechanism for accumulating data into buffers over the course
// of many independent calls. For instance, two objects in the scene might both want to render
// a simple box, but are otherwise unaware of each other. The common code that they call to render
// the box can create buffers to store the rendering parameters for each box and register a function
// that will be called with the accumulated buffer data when the batch commands are finally
// the box can create buffers to store the rendering parameters for each box and register a function
// that will be called with the accumulated buffer data when the batch commands are finally
// executed against the backend
@ -100,15 +100,15 @@ public:
void clear();
// Batches may need to override the context level stereo settings
// if they're performing framebuffer copy operations, like the
// if they're performing framebuffer copy operations, like the
// deferred lighting resolution mechanism
void enableStereo(bool enable = true);
bool isStereoEnabled() const;
// Stereo batches will pre-translate the view matrix, but this isn't
// appropriate for skyboxes or other things intended to be drawn at
// infinite distance, so provide a mechanism to render in stereo
// without the pre-translation of the view.
// Stereo batches will pre-translate the view matrix, but this isn't
// appropriate for skyboxes or other things intended to be drawn at
// infinite distance, so provide a mechanism to render in stereo
// without the pre-translation of the view.
void enableSkybox(bool enable = true);
bool isSkyboxEnabled() const;
@ -147,7 +147,7 @@ public:
// Indirect buffer is used by the multiDrawXXXIndirect calls
// The indirect buffer contains the command descriptions to execute multiple drawcalls in a single call
void setIndirectBuffer(const BufferPointer& buffer, Offset offset = 0, Offset stride = 0);
// multi command desctription for multiDrawIndexedIndirect
class DrawIndirectCommand {
public:
@ -248,7 +248,7 @@ public:
void popProfileRange();
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
// code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
// For now, instead of calling the raw gl Call, use the equivalent call on the batch so the call is beeing recorded
// THe implementation of these functions is in GLBackend.cpp
@ -287,8 +287,6 @@ public:
_glUniformMatrix3fv(location, 1, false, glm::value_ptr(v));
}
void _glColor4f(float red, float green, float blue, float alpha);
// Maybe useful but shoudln't be public. Please convince me otherwise
// Well porting to gles i need it...
void runLambda(std::function<void()> f);
@ -350,7 +348,7 @@ public:
COMMAND_stopNamedCall,
// TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long
// code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
COMMAND_glUniform1i,
COMMAND_glUniform1f,
@ -363,8 +361,6 @@ public:
COMMAND_glUniformMatrix3fv,
COMMAND_glUniformMatrix4fv,
COMMAND_glColor4f,
COMMAND_pushProfileRange,
COMMAND_popProfileRange,
@ -381,7 +377,7 @@ public:
union {
#if (QT_POINTER_SIZE == 8)
size_t _size;
#endif
#endif
int32 _int;
uint32 _uint;
float _float;
@ -389,7 +385,7 @@ public:
};
#if (QT_POINTER_SIZE == 8)
Param(size_t val) : _size(val) {}
#endif
#endif
Param(int32 val) : _int(val) {}
Param(uint32 val) : _uint(val) {}
Param(float val) : _float(val) {}
@ -406,7 +402,7 @@ public:
public:
typedef T Data;
Data _data;
Cache<T>(const Data& data) : _data(data) {}
Cache(const Data& data) : _data(data) {}
static size_t _max;
class Vector {
@ -573,7 +569,7 @@ private:
#else
#define PROFILE_RANGE_BATCH(batch, name)
#define PROFILE_RANGE_BATCH(batch, name)
#endif

View file

@ -60,7 +60,7 @@ public:
Size getNumTypedElements() const { return getSize() / sizeof(T); };
const Byte* getData() const { return getSysmem().readData(); }
// Resize the buffer
// Keep previous data [0 to min(pSize, mSize)]
Size resize(Size pSize);
@ -95,7 +95,7 @@ public:
// \return the number of bytes copied
Size append(Size size, const Byte* data);
template <typename T>
template <typename T>
Size append(const T& t) {
return append(sizeof(t), reinterpret_cast<const Byte*>(&t));
}
@ -110,10 +110,10 @@ public:
const GPUObjectPointer gpuObject {};
// Access the sysmem object, limited to ourselves and GPUObject derived classes
const Sysmem& getSysmem() const { return _sysmem; }
bool isDirty() const {
return _pages(PageManager::DIRTY);
}
@ -127,7 +127,7 @@ protected:
// For use by the render thread to avoid the intermediate step of getUpdate/applyUpdate
void flush() const;
// FIXME don't maintain a second buffer continuously. We should be able to apply updates
// FIXME don't maintain a second buffer continuously. We should be able to apply updates
// directly to the GL object and discard _renderSysmem and _renderPages
mutable PageManager _renderPages;
mutable Sysmem _renderSysmem;
@ -292,7 +292,7 @@ public:
// Direct memory access to the buffer contents is incompatible with the paging memory scheme
template <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0), _stride); }
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>()), _stride); }
#else
#else
template <typename T> Iterator<const T> begin() const { return Iterator<const T>(&get<T>(), _stride); }
template <typename T> Iterator<const T> end() const {
// reimplement get<T> without bounds checking
@ -378,7 +378,7 @@ public:
return *(reinterpret_cast<T*> (_buffer->editData() + elementOffset));
}
};
template <class T> class StructBuffer : public gpu::BufferView {
public:
@ -387,8 +387,8 @@ public:
U t;
return std::make_shared<gpu::Buffer>(sizeof(U), (const gpu::Byte*) &t, sizeof(U));
}
~StructBuffer<T>() {};
StructBuffer<T>() : gpu::BufferView(makeBuffer<T>()) {}
~StructBuffer() {};
StructBuffer() : gpu::BufferView(makeBuffer<T>()) {}
T& edit() {

View file

@ -238,10 +238,14 @@ const Backend::TransformCamera& Backend::TransformCamera::recomputeDerived(const
Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const StereoState& _stereo, const Transform& xformView, Vec2 normalizedJitter) const {
TransformCamera result = *this;
Transform offsetTransform = xformView;
if (!_stereo._skybox) {
offsetTransform.postTranslate(-Vec3(_stereo._eyeViews[eye][3]));
glm::vec3 eyePosition = extractTranslation(_stereo._eyeViews[eye]);
glm::quat eyeOrientation = glmExtractRotation(_stereo._eyeViews[eye]);
if (!_stereo._skybox)
{
offsetTransform.postRotate(eyeOrientation).postTranslate(eyePosition);
} else {
// FIXME: If "skybox" the ipd is set to 0 for now, let s try to propose a better solution for this in the future
offsetTransform.postRotate(eyeOrientation);
}
result._projection = _stereo._eyeProjections[eye];
normalizedJitter.x *= 2.0f;

View file

@ -201,8 +201,6 @@ constexpr const char* COMMAND_NAMES[] = {
"glUniformMatrix3fv",
"glUniformMatrix4fv",
"glColor4f",
"pushProfileRange",
"popProfileRange",
};

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