mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 04:12:46 +02:00
Merge remote-tracking branch 'upstream/master' into feature/quest
This commit is contained in:
commit
0f4d1f073b
137 changed files with 697 additions and 602 deletions
|
@ -24,6 +24,7 @@ import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -54,6 +55,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
public static final String DOMAIN_URL = "url";
|
public static final String DOMAIN_URL = "url";
|
||||||
public static final String EXTRA_GOTO_USERNAME = "gotousername";
|
public static final String EXTRA_GOTO_USERNAME = "gotousername";
|
||||||
private static final String TAG = "Interface";
|
private static final String TAG = "Interface";
|
||||||
|
public static final String EXTRA_ARGS = "args";
|
||||||
private static final int WEB_DRAWER_RIGHT_MARGIN = 262;
|
private static final int WEB_DRAWER_RIGHT_MARGIN = 262;
|
||||||
private static final int WEB_DRAWER_BOTTOM_MARGIN = 150;
|
private static final int WEB_DRAWER_BOTTOM_MARGIN = 150;
|
||||||
private static final int NORMAL_DPI = 160;
|
private static final int NORMAL_DPI = 160;
|
||||||
|
@ -78,6 +80,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
|
|
||||||
private boolean nativeEnterBackgroundCallEnqueued = false;
|
private boolean nativeEnterBackgroundCallEnqueued = false;
|
||||||
private SlidingDrawer mWebSlidingDrawer;
|
private SlidingDrawer mWebSlidingDrawer;
|
||||||
|
private boolean mStartInDomain;
|
||||||
// private GvrApi gvrApi;
|
// private GvrApi gvrApi;
|
||||||
// Opaque native pointer to the Application C++ object.
|
// Opaque native pointer to the Application C++ object.
|
||||||
// This object is owned by the InterfaceActivity instance and passed to the native methods.
|
// This object is owned by the InterfaceActivity instance and passed to the native methods.
|
||||||
|
@ -93,8 +96,14 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.isLoading = true;
|
super.isLoading = true;
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
if (intent.hasExtra(DOMAIN_URL) && !intent.getStringExtra(DOMAIN_URL).isEmpty()) {
|
if (intent.hasExtra(DOMAIN_URL) && !TextUtils.isEmpty(intent.getStringExtra(DOMAIN_URL))) {
|
||||||
intent.putExtra("applicationArguments", "--url " + intent.getStringExtra(DOMAIN_URL));
|
intent.putExtra("applicationArguments", "--url " + intent.getStringExtra(DOMAIN_URL));
|
||||||
|
} else if (intent.hasExtra(EXTRA_ARGS)) {
|
||||||
|
String args = intent.getStringExtra(EXTRA_ARGS);
|
||||||
|
if (!TextUtils.isEmpty(args)) {
|
||||||
|
mStartInDomain = true;
|
||||||
|
intent.putExtra("applicationArguments", args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
@ -125,7 +134,10 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
getActionBar().hide();
|
getActionBar().hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
startActivity(new Intent(this, SplashActivity.class));
|
Intent splashIntent = new Intent(this, SplashActivity.class);
|
||||||
|
splashIntent.putExtra(SplashActivity.EXTRA_START_IN_DOMAIN, mStartInDomain);
|
||||||
|
startActivity(splashIntent);
|
||||||
|
|
||||||
mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
||||||
headsetStateReceiver = new HeadsetStateReceiver();
|
headsetStateReceiver = new HeadsetStateReceiver();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -27,9 +28,14 @@ public class PermissionChecker extends Activity {
|
||||||
private static final boolean CHOOSE_AVATAR_ON_STARTUP = false;
|
private static final boolean CHOOSE_AVATAR_ON_STARTUP = false;
|
||||||
private static final String TAG = "Interface";
|
private static final String TAG = "Interface";
|
||||||
|
|
||||||
|
private static final String EXTRA_ARGS = "args";
|
||||||
|
private String mArgs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
mArgs =(getIntent().getStringExtra(EXTRA_ARGS));
|
||||||
|
|
||||||
Intent myIntent = new Intent(this, BreakpadUploaderService.class);
|
Intent myIntent = new Intent(this, BreakpadUploaderService.class);
|
||||||
startService(myIntent);
|
startService(myIntent);
|
||||||
if (CHOOSE_AVATAR_ON_STARTUP) {
|
if (CHOOSE_AVATAR_ON_STARTUP) {
|
||||||
|
@ -76,6 +82,11 @@ public class PermissionChecker extends Activity {
|
||||||
|
|
||||||
private void launchActivityWithPermissions(){
|
private void launchActivityWithPermissions(){
|
||||||
Intent i = new Intent(this, InterfaceActivity.class);
|
Intent i = new Intent(this, InterfaceActivity.class);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(mArgs)) {
|
||||||
|
i.putExtra(EXTRA_ARGS, mArgs);
|
||||||
|
}
|
||||||
|
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ import android.view.View;
|
||||||
|
|
||||||
public class SplashActivity extends Activity {
|
public class SplashActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String EXTRA_START_IN_DOMAIN = "start-in-domain";
|
||||||
|
private boolean mStartInDomain;
|
||||||
|
|
||||||
private native void registerLoadCompleteListener();
|
private native void registerLoadCompleteListener();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,13 +39,27 @@ public class SplashActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAppLoadedComplete() {
|
public void onAppLoadedComplete() {
|
||||||
if (HifiUtils.getInstance().isUserLoggedIn()) {
|
if (!mStartInDomain) {
|
||||||
startActivity(new Intent(this, MainActivity.class));
|
if (HifiUtils.getInstance().isUserLoggedIn()) {
|
||||||
} else {
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
Intent menuIntent = new Intent(this, LoginMenuActivity.class);
|
} else {
|
||||||
menuIntent.putExtra(LoginMenuActivity.EXTRA_FINISH_ON_BACK, true);
|
Intent menuIntent = new Intent(this, LoginMenuActivity.class);
|
||||||
startActivity(menuIntent);
|
menuIntent.putExtra(LoginMenuActivity.EXTRA_FINISH_ON_BACK, true);
|
||||||
|
startActivity(menuIntent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SplashActivity.this.finish();
|
SplashActivity.this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putBoolean(EXTRA_START_IN_DOMAIN, mStartInDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
mStartInDomain = savedInstanceState.getBoolean(EXTRA_START_IN_DOMAIN, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ bool EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
||||||
newView.lodScaleFactor = powf(2.0f, lodLevelOffset);
|
newView.lodScaleFactor = powf(2.0f, lodLevelOffset);
|
||||||
|
|
||||||
startNewTraversal(newView, root);
|
startNewTraversal(newView, root, isFullScene);
|
||||||
|
|
||||||
// When the viewFrustum changed the sort order may be incorrect, so we re-sort
|
// When the viewFrustum changed the sort order may be incorrect, so we re-sort
|
||||||
// and also use the opportunity to cull anything no longer in view
|
// and also use the opportunity to cull anything no longer in view
|
||||||
|
@ -220,9 +220,10 @@ bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& fil
|
||||||
return hasNewChild || hasNewDescendants;
|
return hasNewChild || hasNewDescendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root) {
|
void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root,
|
||||||
|
bool forceFirstPass) {
|
||||||
|
|
||||||
DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root);
|
DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, forceFirstPass);
|
||||||
// there are three types of traversal:
|
// there are three types of traversal:
|
||||||
//
|
//
|
||||||
// (1) FirstTime = at login --> find everything in view
|
// (1) FirstTime = at login --> find everything in view
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||||
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||||
|
|
||||||
void startNewTraversal(const DiffTraversal::View& viewFrustum, EntityTreeElementPointer root);
|
void startNewTraversal(const DiffTraversal::View& viewFrustum, EntityTreeElementPointer root, bool forceFirstPass = false);
|
||||||
bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) override;
|
bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) override;
|
||||||
|
|
||||||
void preDistributionProcessing() override;
|
void preDistributionProcessing() override;
|
||||||
|
|
|
@ -333,7 +333,11 @@ if (APPLE)
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
||||||
"${RESOURCES_DEV_DIR}/fonts"
|
"${RESOURCES_DEV_DIR}/fonts"
|
||||||
# add redirect json to macOS builds.
|
#copy serverless for android
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
|
"${PROJECT_SOURCE_DIR}/resources/serverless"
|
||||||
|
"${RESOURCES_DEV_DIR}/serverless"
|
||||||
|
# add redirect json to macOS builds.
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
"${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json"
|
"${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json"
|
||||||
"${RESOURCES_DEV_DIR}/serverless/redirect.json"
|
"${RESOURCES_DEV_DIR}/serverless/redirect.json"
|
||||||
|
|
|
@ -1,275 +0,0 @@
|
||||||
import QtQuick 2.5
|
|
||||||
import QtWebChannel 1.0
|
|
||||||
import QtWebEngine 1.5
|
|
||||||
|
|
||||||
import controlsUit 1.0
|
|
||||||
import stylesUit 1.0
|
|
||||||
import "qrc:////qml//windows"
|
|
||||||
|
|
||||||
ScrollingWindow {
|
|
||||||
id: root
|
|
||||||
HifiConstants { id: hifi }
|
|
||||||
//HifiStyles.HifiConstants { id: hifistyles }
|
|
||||||
title: "Browser"
|
|
||||||
resizable: true
|
|
||||||
destroyOnHidden: true
|
|
||||||
width: 800
|
|
||||||
height: 600
|
|
||||||
property variant permissionsBar: {'securityOrigin':'none','feature':'none'}
|
|
||||||
property alias url: webview.url
|
|
||||||
property alias webView: webview
|
|
||||||
|
|
||||||
signal loadingChanged(int status)
|
|
||||||
|
|
||||||
x: 100
|
|
||||||
y: 100
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
focus = true
|
|
||||||
shown = true
|
|
||||||
addressBar.text = webview.url
|
|
||||||
}
|
|
||||||
|
|
||||||
function setProfile(profile) {
|
|
||||||
webview.profile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showPermissionsBar(){
|
|
||||||
permissionsContainer.visible=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hidePermissionsBar(){
|
|
||||||
permissionsContainer.visible=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function allowPermissions(){
|
|
||||||
webview.grantFeaturePermission(permissionsBar.securityOrigin, permissionsBar.feature, true);
|
|
||||||
hidePermissionsBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAutoAdd(auto) {
|
|
||||||
desktop.setAutoAdd(auto);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id:item
|
|
||||||
width: pane.contentWidth
|
|
||||||
implicitHeight: pane.scrollHeight
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: buttons
|
|
||||||
spacing: 4
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 8
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 8
|
|
||||||
HiFiGlyphs {
|
|
||||||
id: back;
|
|
||||||
enabled: webview.canGoBack;
|
|
||||||
text: hifi.glyphs.backward
|
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
|
||||||
size: 48
|
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goBack() }
|
|
||||||
}
|
|
||||||
|
|
||||||
HiFiGlyphs {
|
|
||||||
id: forward;
|
|
||||||
enabled: webview.canGoForward;
|
|
||||||
text: hifi.glyphs.forward
|
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
|
||||||
size: 48
|
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
|
||||||
}
|
|
||||||
|
|
||||||
HiFiGlyphs {
|
|
||||||
id: reload;
|
|
||||||
enabled: webview.canGoForward;
|
|
||||||
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload
|
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
|
||||||
size: 48
|
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: border
|
|
||||||
height: 48
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 8
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
anchors.left: buttons.right
|
|
||||||
anchors.leftMargin: 8
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: barIcon
|
|
||||||
width: parent.height
|
|
||||||
height: parent.height
|
|
||||||
Image {
|
|
||||||
source: webview.icon;
|
|
||||||
x: (parent.height - height) / 2
|
|
||||||
y: (parent.width - width) / 2
|
|
||||||
sourceSize: Qt.size(width, height);
|
|
||||||
verticalAlignment: Image.AlignVCenter;
|
|
||||||
horizontalAlignment: Image.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: addressBar
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
anchors.left: barIcon.right
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
focus: true
|
|
||||||
colorScheme: hifi.colorSchemes.dark
|
|
||||||
placeholderText: "Enter URL"
|
|
||||||
Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i")
|
|
||||||
Keys.onPressed: {
|
|
||||||
switch(event.key) {
|
|
||||||
case Qt.Key_Enter:
|
|
||||||
case Qt.Key_Return:
|
|
||||||
event.accepted = true
|
|
||||||
if (text.indexOf("http") != 0) {
|
|
||||||
text = "http://" + text;
|
|
||||||
}
|
|
||||||
root.hidePermissionsBar();
|
|
||||||
root.keyboardRaised = false;
|
|
||||||
webview.url = text;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id:permissionsContainer
|
|
||||||
visible:false
|
|
||||||
color: "#000000"
|
|
||||||
width: parent.width
|
|
||||||
anchors.top: buttons.bottom
|
|
||||||
height:40
|
|
||||||
z:100
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop { position: 0.0; color: "black" }
|
|
||||||
GradientStop { position: 1.0; color: "grey" }
|
|
||||||
}
|
|
||||||
|
|
||||||
RalewayLight {
|
|
||||||
id: permissionsInfo
|
|
||||||
anchors.right:permissionsRow.left
|
|
||||||
anchors.rightMargin: 32
|
|
||||||
anchors.topMargin:8
|
|
||||||
anchors.top:parent.top
|
|
||||||
text: "This site wants to use your microphone/camera"
|
|
||||||
size: 18
|
|
||||||
color: hifi.colors.white
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: permissionsRow
|
|
||||||
spacing: 4
|
|
||||||
anchors.top:parent.top
|
|
||||||
anchors.topMargin: 8
|
|
||||||
anchors.right: parent.right
|
|
||||||
visible: true
|
|
||||||
z:101
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id:allow
|
|
||||||
text: "Allow"
|
|
||||||
color: hifi.buttons.blue
|
|
||||||
colorScheme: root.colorScheme
|
|
||||||
width: 120
|
|
||||||
enabled: true
|
|
||||||
onClicked: root.allowPermissions();
|
|
||||||
z:101
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id:block
|
|
||||||
text: "Block"
|
|
||||||
color: hifi.buttons.red
|
|
||||||
colorScheme: root.colorScheme
|
|
||||||
width: 120
|
|
||||||
enabled: true
|
|
||||||
onClicked: root.hidePermissionsBar();
|
|
||||||
z:101
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WebView {
|
|
||||||
id: webview
|
|
||||||
url: "https://highfidelity.com/"
|
|
||||||
profile: FileTypeProfile;
|
|
||||||
|
|
||||||
// Create a global EventBridge object for raiseAndLowerKeyboard.
|
|
||||||
WebEngineScript {
|
|
||||||
id: createGlobalEventBridge
|
|
||||||
sourceCode: eventBridgeJavaScriptToInject
|
|
||||||
injectionPoint: WebEngineScript.Deferred
|
|
||||||
worldId: WebEngineScript.MainWorld
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect when may want to raise and lower keyboard.
|
|
||||||
WebEngineScript {
|
|
||||||
id: raiseAndLowerKeyboard
|
|
||||||
injectionPoint: WebEngineScript.Deferred
|
|
||||||
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
|
|
||||||
worldId: WebEngineScript.MainWorld
|
|
||||||
}
|
|
||||||
|
|
||||||
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ]
|
|
||||||
|
|
||||||
anchors.top: buttons.bottom
|
|
||||||
anchors.topMargin: 8
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
onFeaturePermissionRequested: {
|
|
||||||
if (feature == 2) { // QWebEnginePage::MediaAudioCapture
|
|
||||||
grantFeaturePermission(securityOrigin, feature, true);
|
|
||||||
} else {
|
|
||||||
permissionsBar.securityOrigin = securityOrigin;
|
|
||||||
permissionsBar.feature = feature;
|
|
||||||
root.showPermissionsBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoadingChanged: {
|
|
||||||
if (loadRequest.status === WebEngineView.LoadSucceededStatus) {
|
|
||||||
addressBar.text = loadRequest.url
|
|
||||||
}
|
|
||||||
root.loadingChanged(loadRequest.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
onWindowCloseRequested: {
|
|
||||||
root.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
webChannel.registerObject("eventBridge", eventBridge);
|
|
||||||
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
|
|
||||||
desktop.initWebviewProfileHandlers(webview.profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // item
|
|
||||||
|
|
||||||
|
|
||||||
Keys.onPressed: {
|
|
||||||
switch(event.key) {
|
|
||||||
case Qt.Key_L:
|
|
||||||
if (event.modifiers == Qt.ControlModifier) {
|
|
||||||
event.accepted = true
|
|
||||||
addressBar.selectAll()
|
|
||||||
addressBar.forceActiveFocus()
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // dialog
|
|
58
interface/resources/qml/+webengine/BrowserWebView.qml
Normal file
58
interface/resources/qml/+webengine/BrowserWebView.qml
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtWebChannel 1.0
|
||||||
|
import QtWebEngine 1.5
|
||||||
|
|
||||||
|
import controlsUit 1.0
|
||||||
|
|
||||||
|
WebView {
|
||||||
|
id: webview
|
||||||
|
url: "https://highfidelity.com/"
|
||||||
|
profile: FileTypeProfile;
|
||||||
|
|
||||||
|
property var parentRoot: null
|
||||||
|
|
||||||
|
// Create a global EventBridge object for raiseAndLowerKeyboard.
|
||||||
|
WebEngineScript {
|
||||||
|
id: createGlobalEventBridge
|
||||||
|
sourceCode: eventBridgeJavaScriptToInject
|
||||||
|
injectionPoint: WebEngineScript.Deferred
|
||||||
|
worldId: WebEngineScript.MainWorld
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect when may want to raise and lower keyboard.
|
||||||
|
WebEngineScript {
|
||||||
|
id: raiseAndLowerKeyboard
|
||||||
|
injectionPoint: WebEngineScript.Deferred
|
||||||
|
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
|
||||||
|
worldId: WebEngineScript.MainWorld
|
||||||
|
}
|
||||||
|
|
||||||
|
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ]
|
||||||
|
|
||||||
|
onFeaturePermissionRequested: {
|
||||||
|
if (feature == 2) { // QWebEnginePage::MediaAudioCapture
|
||||||
|
grantFeaturePermission(securityOrigin, feature, true);
|
||||||
|
} else {
|
||||||
|
permissionsBar.securityOrigin = securityOrigin;
|
||||||
|
permissionsBar.feature = feature;
|
||||||
|
parentRoot.showPermissionsBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoadingChanged: {
|
||||||
|
if (loadRequest.status === WebEngineView.LoadSucceededStatus) {
|
||||||
|
addressBar.text = loadRequest.url
|
||||||
|
}
|
||||||
|
parentRoot.loadingChanged(loadRequest.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowCloseRequested: {
|
||||||
|
parentRoot.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
webChannel.registerObject("eventBridge", eventBridge);
|
||||||
|
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
|
||||||
|
desktop.initWebviewProfileHandlers(webview.profile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,50 +0,0 @@
|
||||||
//
|
|
||||||
// InfoView.qml
|
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 27 Apr 2015
|
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
import QtQuick 2.5
|
|
||||||
import Hifi 1.0 as Hifi
|
|
||||||
|
|
||||||
import controlsUit 1.0
|
|
||||||
import "qrc:////qml//windows" as Windows
|
|
||||||
|
|
||||||
Windows.ScrollingWindow {
|
|
||||||
id: root
|
|
||||||
width: 800
|
|
||||||
height: 800
|
|
||||||
resizable: true
|
|
||||||
|
|
||||||
Hifi.InfoView {
|
|
||||||
id: infoView
|
|
||||||
width: pane.contentWidth
|
|
||||||
implicitHeight: pane.scrollHeight
|
|
||||||
|
|
||||||
WebView {
|
|
||||||
id: webview
|
|
||||||
objectName: "WebView"
|
|
||||||
anchors.fill: parent
|
|
||||||
url: infoView.url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
centerWindow(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
centerWindow(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function centerWindow() {
|
|
||||||
desktop.centerOnVisible(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
//
|
|
||||||
// QmlWebWindow.qml
|
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 17 Dec 2015
|
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
import QtQuick 2.5
|
|
||||||
import QtWebEngine 1.1
|
|
||||||
import QtWebChannel 1.0
|
|
||||||
|
|
||||||
import "qrc:////qml//windows" as Windows
|
|
||||||
import controlsUit 1.0 as Controls
|
|
||||||
import stylesUit 1.0
|
|
||||||
|
|
||||||
Windows.ScrollingWindow {
|
|
||||||
id: root
|
|
||||||
HifiConstants { id: hifi }
|
|
||||||
title: "WebWindow"
|
|
||||||
resizable: true
|
|
||||||
shown: false
|
|
||||||
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
|
||||||
destroyOnCloseButton: false
|
|
||||||
property alias source: webview.url
|
|
||||||
property alias scriptUrl: webview.userScriptUrl
|
|
||||||
|
|
||||||
// This is for JS/QML communication, which is unused in a WebWindow,
|
|
||||||
// but not having this here results in spurious warnings about a
|
|
||||||
// missing signal
|
|
||||||
signal sendToScript(var message);
|
|
||||||
|
|
||||||
signal moved(vector2d position);
|
|
||||||
signal resized(size size);
|
|
||||||
|
|
||||||
function notifyMoved() {
|
|
||||||
moved(Qt.vector2d(x, y));
|
|
||||||
}
|
|
||||||
|
|
||||||
function notifyResized() {
|
|
||||||
resized(Qt.size(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
onXChanged: notifyMoved();
|
|
||||||
onYChanged: notifyMoved();
|
|
||||||
|
|
||||||
onWidthChanged: notifyResized();
|
|
||||||
onHeightChanged: notifyResized();
|
|
||||||
|
|
||||||
onShownChanged: {
|
|
||||||
keyboardEnabled = HMD.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: pane.contentWidth
|
|
||||||
implicitHeight: pane.scrollHeight
|
|
||||||
|
|
||||||
Controls.WebView {
|
|
||||||
id: webview
|
|
||||||
url: "about:blank"
|
|
||||||
anchors.fill: parent
|
|
||||||
focus: true
|
|
||||||
profile: HFWebEngineProfile;
|
|
||||||
|
|
||||||
property string userScriptUrl: ""
|
|
||||||
|
|
||||||
// Create a global EventBridge object for raiseAndLowerKeyboard.
|
|
||||||
WebEngineScript {
|
|
||||||
id: createGlobalEventBridge
|
|
||||||
sourceCode: eventBridgeJavaScriptToInject
|
|
||||||
injectionPoint: WebEngineScript.DocumentCreation
|
|
||||||
worldId: WebEngineScript.MainWorld
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect when may want to raise and lower keyboard.
|
|
||||||
WebEngineScript {
|
|
||||||
id: raiseAndLowerKeyboard
|
|
||||||
injectionPoint: WebEngineScript.Deferred
|
|
||||||
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
|
|
||||||
worldId: WebEngineScript.MainWorld
|
|
||||||
}
|
|
||||||
|
|
||||||
// User script.
|
|
||||||
WebEngineScript {
|
|
||||||
id: userScript
|
|
||||||
sourceUrl: webview.userScriptUrl
|
|
||||||
injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished.
|
|
||||||
worldId: WebEngineScript.MainWorld
|
|
||||||
}
|
|
||||||
|
|
||||||
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ]
|
|
||||||
|
|
||||||
function onWebEventReceived(event) {
|
|
||||||
if (event.slice(0, 17) === "CLARA.IO DOWNLOAD") {
|
|
||||||
ApplicationInterface.addAssetToWorldFromURL(event.slice(18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
webChannel.registerObject("eventBridge", eventBridge);
|
|
||||||
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
|
|
||||||
eventBridge.webEventReceived.connect(onWebEventReceived);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
53
interface/resources/qml/+webengine/QmlWebWindowView.qml
Normal file
53
interface/resources/qml/+webengine/QmlWebWindowView.qml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtWebEngine 1.1
|
||||||
|
import QtWebChannel 1.0
|
||||||
|
|
||||||
|
import controlsUit 1.0 as Controls
|
||||||
|
import stylesUit 1.0
|
||||||
|
Controls.WebView {
|
||||||
|
id: webview
|
||||||
|
url: "about:blank"
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: true
|
||||||
|
profile: HFWebEngineProfile;
|
||||||
|
|
||||||
|
property string userScriptUrl: ""
|
||||||
|
|
||||||
|
// Create a global EventBridge object for raiseAndLowerKeyboard.
|
||||||
|
WebEngineScript {
|
||||||
|
id: createGlobalEventBridge
|
||||||
|
sourceCode: eventBridgeJavaScriptToInject
|
||||||
|
injectionPoint: WebEngineScript.DocumentCreation
|
||||||
|
worldId: WebEngineScript.MainWorld
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect when may want to raise and lower keyboard.
|
||||||
|
WebEngineScript {
|
||||||
|
id: raiseAndLowerKeyboard
|
||||||
|
injectionPoint: WebEngineScript.Deferred
|
||||||
|
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
|
||||||
|
worldId: WebEngineScript.MainWorld
|
||||||
|
}
|
||||||
|
|
||||||
|
// User script.
|
||||||
|
WebEngineScript {
|
||||||
|
id: userScript
|
||||||
|
sourceUrl: webview.userScriptUrl
|
||||||
|
injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished.
|
||||||
|
worldId: WebEngineScript.MainWorld
|
||||||
|
}
|
||||||
|
|
||||||
|
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ]
|
||||||
|
|
||||||
|
function onWebEventReceived(event) {
|
||||||
|
if (event.slice(0, 17) === "CLARA.IO DOWNLOAD") {
|
||||||
|
ApplicationInterface.addAssetToWorldFromURL(event.slice(18));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
webChannel.registerObject("eventBridge", eventBridge);
|
||||||
|
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
|
||||||
|
eventBridge.webEventReceived.connect(onWebEventReceived);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
|
|
||||||
import controlsUit 1.0
|
import controlsUit 1.0
|
||||||
import stylesUit 1.0
|
import stylesUit 1.0
|
||||||
|
|
||||||
import "windows"
|
import "windows"
|
||||||
|
import "."
|
||||||
|
|
||||||
ScrollingWindow {
|
ScrollingWindow {
|
||||||
id: root
|
id: root
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
//HifiStyles.HifiConstants { id: hifistyles }
|
|
||||||
title: "Browser"
|
title: "Browser"
|
||||||
resizable: true
|
resizable: true
|
||||||
destroyOnHidden: true
|
destroyOnHidden: true
|
||||||
|
@ -30,6 +29,7 @@ ScrollingWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setProfile(profile) {
|
function setProfile(profile) {
|
||||||
|
webview.profile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPermissionsBar(){
|
function showPermissionsBar(){
|
||||||
|
@ -41,6 +41,7 @@ ScrollingWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowPermissions(){
|
function allowPermissions(){
|
||||||
|
webview.grantFeaturePermission(permissionsBar.securityOrigin, permissionsBar.feature, true);
|
||||||
hidePermissionsBar();
|
hidePermissionsBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,10 +199,15 @@ ScrollingWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyWebView {
|
BrowserWebView {
|
||||||
id: webview
|
id: webview
|
||||||
anchors.centerIn: parent
|
parentRoot: root
|
||||||
url: "https://highfidelity.com/"
|
|
||||||
|
anchors.top: buttons.bottom
|
||||||
|
anchors.topMargin: 8
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
}
|
}
|
||||||
|
|
||||||
} // item
|
} // item
|
||||||
|
|
8
interface/resources/qml/BrowserWebView.qml
Normal file
8
interface/resources/qml/BrowserWebView.qml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import controlsUit 1.0
|
||||||
|
|
||||||
|
ProxyWebView {
|
||||||
|
property var parentRoot: null
|
||||||
|
|
||||||
|
function grantFeaturePermission(origin, feature) {}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ Windows.ScrollingWindow {
|
||||||
width: pane.contentWidth
|
width: pane.contentWidth
|
||||||
implicitHeight: pane.scrollHeight
|
implicitHeight: pane.scrollHeight
|
||||||
|
|
||||||
ProxyWebView {
|
BaseWebView {
|
||||||
id: webview
|
id: webview
|
||||||
objectName: "WebView"
|
objectName: "WebView"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
|
|
||||||
import "windows" as Windows
|
import "windows" as Windows
|
||||||
|
import "."
|
||||||
import controlsUit 1.0 as Controls
|
import controlsUit 1.0 as Controls
|
||||||
import stylesUit 1.0
|
import stylesUit 1.0
|
||||||
|
|
||||||
|
@ -55,12 +56,8 @@ Windows.ScrollingWindow {
|
||||||
width: pane.contentWidth
|
width: pane.contentWidth
|
||||||
implicitHeight: pane.scrollHeight
|
implicitHeight: pane.scrollHeight
|
||||||
|
|
||||||
Controls.WebView {
|
QmlWebWindowView {
|
||||||
id: webview
|
id: webview
|
||||||
url: "about:blank"
|
|
||||||
property string userScriptUrl: ""
|
|
||||||
anchors.fill: parent
|
|
||||||
focus: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
interface/resources/qml/QmlWebWindowView.qml
Normal file
5
interface/resources/qml/QmlWebWindowView.qml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import controlsUit 1.0
|
||||||
|
|
||||||
|
BaseWebView {
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ Rectangle {
|
||||||
|
|
||||||
property bool safeLoading: false
|
property bool safeLoading: false
|
||||||
property bool loadingLatched: false
|
property bool loadingLatched: false
|
||||||
|
property bool loading: false
|
||||||
property var loadingRequest: null
|
property var loadingRequest: null
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ Rectangle {
|
||||||
HifiControlsUit.Keyboard {
|
HifiControlsUit.Keyboard {
|
||||||
id: keyboard
|
id: keyboard
|
||||||
z: 1000
|
z: 1000
|
||||||
raised: parent.keyboardEnabled && parent.keyboardRaised
|
raised: parent.keyboardEnabled && parent.keyboardRaised && HMD.active
|
||||||
numeric: parent.punctuationMode
|
numeric: parent.punctuationMode
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtWebEngine 1.5
|
||||||
|
import "../../controls" as Controls
|
||||||
|
|
||||||
|
Controls.TabletWebView {
|
||||||
|
profile: WebEngineProfile { httpUserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"}
|
||||||
|
}
|
|
@ -20,7 +20,8 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
*
|
* @hifi-avatar
|
||||||
|
*
|
||||||
* @property {string} buildDate
|
* @property {string} buildDate
|
||||||
* @property {string} buildVersion
|
* @property {string} buildVersion
|
||||||
* @property {string} qtVersion
|
* @property {string} qtVersion
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class AABox;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} presentTime <em>Read-only.</em>
|
* @property {number} presentTime <em>Read-only.</em>
|
||||||
* @property {number} engineRunTime <em>Read-only.</em>
|
* @property {number} engineRunTime <em>Read-only.</em>
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class LocationBookmarks : public Bookmarks, public Dependency {
|
class LocationBookmarks : public Bookmarks, public Dependency {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
class SpeechRecognizer : public QObject, public Dependency {
|
class SpeechRecognizer : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -31,6 +31,7 @@ class AudioScope : public QObject, public Dependency {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} scopeInput <em>Read-only.</em>
|
* @property {number} scopeInput <em>Read-only.</em>
|
||||||
* @property {number} scopeOutputLeft <em>Read-only.</em>
|
* @property {number} scopeOutputLeft <em>Read-only.</em>
|
||||||
|
|
|
@ -46,6 +46,7 @@ using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @borrows AvatarList.getAvatarIdentifiers as getAvatarIdentifiers
|
* @borrows AvatarList.getAvatarIdentifiers as getAvatarIdentifiers
|
||||||
* @borrows AvatarList.getAvatarsInRange as getAvatarsInRange
|
* @borrows AvatarList.getAvatarsInRange as getAvatarsInRange
|
||||||
|
|
|
@ -66,6 +66,7 @@ class MyAvatar : public Avatar {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {Vec3} qmlPosition - A synonym for <code>position</code> for use by QML.
|
* @property {Vec3} qmlPosition - A synonym for <code>position</code> for use by QML.
|
||||||
* @property {boolean} shouldRenderLocally=true - If <code>true</code> then your avatar is rendered for you in Interface,
|
* @property {boolean} shouldRenderLocally=true - If <code>true</code> then your avatar is rendered for you in Interface,
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DdeFaceTracker : public FaceTracker, public Dependency {
|
class DdeFaceTracker : public FaceTracker, public Dependency {
|
||||||
|
|
|
@ -27,6 +27,7 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} PICK_ENTITIES A filter flag. Include domain and avatar entities when intersecting. <em>Read-only.</em>. Deprecated.
|
* @property {number} PICK_ENTITIES A filter flag. Include domain and avatar entities when intersecting. <em>Read-only.</em>. Deprecated.
|
||||||
* @property {number} PICK_OVERLAYS A filter flag. Include local entities when intersecting. <em>Read-only.</em>. Deprecated.
|
* @property {number} PICK_OVERLAYS A filter flag. Include local entities when intersecting. <em>Read-only.</em>. Deprecated.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PointerScriptingInterface : public QObject, public Dependency {
|
class PointerScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} PICK_ENTITIES <em>Read-only.</em>
|
* @property {number} PICK_ENTITIES <em>Read-only.</em>
|
||||||
* @property {number} PICK_OVERLAYS <em>Read-only.</em>
|
* @property {number} PICK_OVERLAYS <em>Read-only.</em>
|
||||||
|
|
|
@ -42,6 +42,7 @@ class AccountServicesScriptingInterface : public QObject {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @namespace AccountServices
|
* @namespace AccountServices
|
||||||
* @property {string} username <em>Read-only.</em>
|
* @property {string} username <em>Read-only.</em>
|
||||||
|
|
|
@ -32,6 +32,7 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
class ClipboardScriptingInterface : public QObject {
|
class ClipboardScriptingInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -199,6 +199,7 @@ class ScriptEngine;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
||||||
* points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
|
* points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
*
|
* @hifi-avatar
|
||||||
|
*
|
||||||
* @property {number} width
|
* @property {number} width
|
||||||
* @property {number} height
|
* @property {number} height
|
||||||
* @property {number} ALWAYS_ON_TOP - InteractiveWindow flag for always showing a window on top
|
* @property {number} ALWAYS_ON_TOP - InteractiveWindow flag for always showing a window on top
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GooglePolyScriptingInterface : public QObject, public Dependency {
|
class GooglePolyScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
|
@ -31,6 +31,7 @@ class QScriptEngine;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise
|
* @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise
|
||||||
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {bool} raised - <code>true</code> If the keyboard is visible <code>false</code> otherwise
|
* @property {bool} raised - <code>true</code> If the keyboard is visible <code>false</code> otherwise
|
||||||
* @property {bool} password - <code>true</code> Will show * instead of characters in the text display <code>false</code> otherwise
|
* @property {bool} password - <code>true</code> Will show * instead of characters in the text display <code>false</code> otherwise
|
||||||
|
|
|
@ -35,6 +35,7 @@ class MenuItemProperties;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @example <caption>Outline an entity when it is grabbed by a controller.</caption>
|
* @example <caption>Outline an entity when it is grabbed by a controller.</caption>
|
||||||
* // Create a box and copy the following text into the entity's "Script URL" field.
|
* // Create a box and copy the following text into the entity's "Script URL" field.
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SettingsScriptingInterface : public QObject {
|
class SettingsScriptingInterface : public QObject {
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} walletStatus
|
* @property {number} walletStatus
|
||||||
* @property {bool} limitedCommerce
|
* @property {bool} limitedCommerce
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other
|
* @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other
|
||||||
* chrome), in pixels. <em>Read-only.</em>
|
* chrome), in pixels. <em>Read-only.</em>
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AvatarInputs : public QObject {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {boolean} cameraEnabled <em>Read-only.</em>
|
* @property {boolean} cameraEnabled <em>Read-only.</em>
|
||||||
* @property {boolean} cameraMuted <em>Read-only.</em>
|
* @property {boolean} cameraMuted <em>Read-only.</em>
|
||||||
|
|
|
@ -42,6 +42,7 @@ private:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Snapshot : public QObject, public Dependency {
|
class Snapshot : public QObject, public Dependency {
|
||||||
|
|
|
@ -27,6 +27,7 @@ private: \
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {Uuid} keyboardFocusOverlay - Get or set the {@link Overlays.OverlayType|web3d} overlay that has keyboard focus.
|
* @property {Uuid} keyboardFocusOverlay - Get or set the {@link Overlays.OverlayType|web3d} overlay that has keyboard focus.
|
||||||
* If no overlay has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
|
* If no overlay has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
|
||||||
|
|
|
@ -4,5 +4,6 @@ link_hifi_libraries(shared graphics fbx)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
||||||
|
include_hifi_library_headers(image)
|
||||||
|
|
||||||
target_nsight()
|
target_nsight()
|
||||||
|
|
|
@ -50,6 +50,7 @@ Q_DECLARE_METATYPE(AnimationPointer)
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,6 +30,7 @@ class AnimationCacheScriptingInterface : public ScriptableResourceCache, public
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||||
|
|
|
@ -44,6 +44,7 @@ class AudioStreamStatsInterface : public QObject {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} lossRate <em>Read-only.</em>
|
* @property {number} lossRate <em>Read-only.</em>
|
||||||
* @property {number} lossCount <em>Read-only.</em>
|
* @property {number} lossCount <em>Read-only.</em>
|
||||||
|
@ -192,6 +193,7 @@ class AudioStatsInterface : public QObject {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} pingMs <em>Read-only.</em>
|
* @property {number} pingMs <em>Read-only.</em>
|
||||||
* @property {number} inputReadMsMax <em>Read-only.</em>
|
* @property {number} inputReadMsMax <em>Read-only.</em>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,7 +61,8 @@ class Sound : public Resource {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sound(const QUrl& url, bool isStereo = false, bool isAmbisonic = false);
|
Sound(const QUrl& url, bool isStereo = false, bool isAmbisonic = false);
|
||||||
|
Sound(const Sound& other) : Resource(other), _audioData(other._audioData), _numChannels(other._numChannels) {}
|
||||||
|
|
||||||
bool isReady() const { return (bool)_audioData; }
|
bool isReady() const { return (bool)_audioData; }
|
||||||
|
|
||||||
bool isStereo() const { return _audioData ? _audioData->isStereo() : false; }
|
bool isStereo() const { return _audioData ? _audioData->isStereo() : false; }
|
||||||
|
@ -132,6 +133,7 @@ typedef QSharedPointer<Sound> SharedSoundPointer;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,6 +30,7 @@ class SoundCacheScriptingInterface : public ScriptableResourceCache, public Depe
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -107,10 +107,11 @@ int ClientTraitsHandler::sendChangedTraitsToMixer() {
|
||||||
|
|
||||||
if (initialSend || *simpleIt == Updated) {
|
if (initialSend || *simpleIt == Updated) {
|
||||||
if (traitType == AvatarTraits::SkeletonModelURL) {
|
if (traitType == AvatarTraits::SkeletonModelURL) {
|
||||||
|
bytesWritten += _owningAvatar->packTrait(traitType, *traitsPacketList);
|
||||||
|
|
||||||
// keep track of our skeleton version in case we get an override back
|
// keep track of our skeleton version in case we get an override back
|
||||||
_currentSkeletonVersion = _currentTraitVersion;
|
_currentSkeletonVersion = _currentTraitVersion;
|
||||||
}
|
}
|
||||||
bytesWritten += _owningAvatar->packTrait(traitType, *traitsPacketList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++simpleIt;
|
++simpleIt;
|
||||||
|
|
|
@ -154,7 +154,7 @@ void TextureBaker::processTexture() {
|
||||||
gpu::BackendTarget::GLES32
|
gpu::BackendTarget::GLES32
|
||||||
}};
|
}};
|
||||||
for (auto target : BACKEND_TARGETS) {
|
for (auto target : BACKEND_TARGETS) {
|
||||||
auto processedTexture = image::processImage(buffer, _textureURL.toString().toStdString(),
|
auto processedTexture = image::processImage(buffer, _textureURL.toString().toStdString(), image::ColorChannel::NONE,
|
||||||
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, true,
|
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, true,
|
||||||
target, _abortProcessing);
|
target, _abortProcessing);
|
||||||
if (!processedTexture) {
|
if (!processedTexture) {
|
||||||
|
@ -197,7 +197,7 @@ void TextureBaker::processTexture() {
|
||||||
// Uncompressed KTX
|
// Uncompressed KTX
|
||||||
if (_textureType == image::TextureUsage::Type::CUBE_TEXTURE) {
|
if (_textureType == image::TextureUsage::Type::CUBE_TEXTURE) {
|
||||||
buffer->reset();
|
buffer->reset();
|
||||||
auto processedTexture = image::processImage(std::move(buffer), _textureURL.toString().toStdString(),
|
auto processedTexture = image::processImage(std::move(buffer), _textureURL.toString().toStdString(), image::ColorChannel::NONE,
|
||||||
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, false, gpu::BackendTarget::GL45, _abortProcessing);
|
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, false, gpu::BackendTarget::GL45, _abortProcessing);
|
||||||
if (!processedTexture) {
|
if (!processedTexture) {
|
||||||
handleError("Could not process texture " + _textureURL.toString());
|
handleError("Could not process texture " + _textureURL.toString());
|
||||||
|
|
|
@ -57,6 +57,7 @@ class UserInputMapper;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -39,6 +39,7 @@ class ScriptingInterface;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO migrate functionality to a RouteBuilder class and make the proxy defer to that
|
// TODO migrate functionality to a RouteBuilder class and make the proxy defer to that
|
||||||
|
|
|
@ -178,6 +178,7 @@ private:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {boolean} allowMouseCapture
|
* @property {boolean} allowMouseCapture
|
||||||
* @property {number} depth
|
* @property {number} depth
|
||||||
|
|
|
@ -193,7 +193,8 @@ DiffTraversal::DiffTraversal() {
|
||||||
_path.reserve(MIN_PATH_DEPTH);
|
_path.reserve(MIN_PATH_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffTraversal::Type DiffTraversal::prepareNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root) {
|
DiffTraversal::Type DiffTraversal::prepareNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root,
|
||||||
|
bool forceFirstPass) {
|
||||||
assert(root);
|
assert(root);
|
||||||
// there are three types of traversal:
|
// there are three types of traversal:
|
||||||
//
|
//
|
||||||
|
@ -212,7 +213,7 @@ DiffTraversal::Type DiffTraversal::prepareNewTraversal(const DiffTraversal::View
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
// If usesViewFrustum changes, treat it as a First traversal
|
// If usesViewFrustum changes, treat it as a First traversal
|
||||||
if (_completedView.startTime == 0 || _currentView.usesViewFrustums() != _completedView.usesViewFrustums()) {
|
if (forceFirstPass || _completedView.startTime == 0 || _currentView.usesViewFrustums() != _completedView.usesViewFrustums()) {
|
||||||
type = Type::First;
|
type = Type::First;
|
||||||
_currentView.viewFrustums = view.viewFrustums;
|
_currentView.viewFrustums = view.viewFrustums;
|
||||||
_currentView.lodScaleFactor = view.lodScaleFactor;
|
_currentView.lodScaleFactor = view.lodScaleFactor;
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
DiffTraversal();
|
DiffTraversal();
|
||||||
|
|
||||||
Type prepareNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root);
|
Type prepareNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root, bool forceFirstPass = false);
|
||||||
|
|
||||||
const View& getCurrentView() const { return _currentView; }
|
const View& getCurrentView() const { return _currentView; }
|
||||||
|
|
||||||
|
|
|
@ -2640,15 +2640,8 @@ bool EntityItem::matchesJSONFilters(const QJsonObject& jsonFilters) const {
|
||||||
|
|
||||||
static const QString SERVER_SCRIPTS_PROPERTY = "serverScripts";
|
static const QString SERVER_SCRIPTS_PROPERTY = "serverScripts";
|
||||||
|
|
||||||
foreach(const auto& property, jsonFilters.keys()) {
|
if (jsonFilters[SERVER_SCRIPTS_PROPERTY] == EntityQueryFilterSymbol::NonDefault) {
|
||||||
if (property == SERVER_SCRIPTS_PROPERTY && jsonFilters[property] == EntityQueryFilterSymbol::NonDefault) {
|
return _serverScripts != ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS;
|
||||||
// check if this entity has a non-default value for serverScripts
|
|
||||||
if (_serverScripts != ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the json filter syntax did not match what we expected, return a match
|
// the json filter syntax did not match what we expected, return a match
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
#include <ResourceManager.h>
|
#include <ResourceManager.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
#include <image/ColorChannel.h>
|
||||||
|
|
||||||
#include "FBXSerializer.h"
|
#include "FBXSerializer.h"
|
||||||
|
|
||||||
|
@ -1146,8 +1147,10 @@ void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& mat
|
||||||
}
|
}
|
||||||
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
|
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
|
||||||
fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||||
|
fbxmat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN;
|
||||||
fbxmat.useRoughnessMap = true;
|
fbxmat.useRoughnessMap = true;
|
||||||
fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||||
|
fbxmat.metallicTexture.sourceChannel = image::ColorChannel::BLUE;
|
||||||
fbxmat.useMetallicMap = true;
|
fbxmat.useMetallicMap = true;
|
||||||
}
|
}
|
||||||
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
||||||
|
|
|
@ -397,8 +397,6 @@ public:
|
||||||
bool isDefined() const { return _defined; }
|
bool isDefined() const { return _defined; }
|
||||||
|
|
||||||
Texture(TextureUsageType usageType);
|
Texture(TextureUsageType usageType);
|
||||||
Texture(const Texture& buf); // deep copy of the sysmem texture
|
|
||||||
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
Stamp getStamp() const { return _stamp; }
|
Stamp getStamp() const { return _stamp; }
|
||||||
|
@ -693,8 +691,10 @@ class TextureSource {
|
||||||
public:
|
public:
|
||||||
TextureSource(const QUrl& url, int type = 0) : _imageUrl(url), _type(type) {}
|
TextureSource(const QUrl& url, int type = 0) : _imageUrl(url), _type(type) {}
|
||||||
|
|
||||||
|
void setUrl(const QUrl& url) { _imageUrl = url; }
|
||||||
const QUrl& getUrl() const { return _imageUrl; }
|
const QUrl& getUrl() const { return _imageUrl; }
|
||||||
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
||||||
|
void setType(int type) { _type = type; }
|
||||||
int getType() const { return _type; }
|
int getType() const { return _type; }
|
||||||
|
|
||||||
void resetTexture(gpu::TexturePointer texture);
|
void resetTexture(gpu::TexturePointer texture);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GraphicsScriptingInterface : public QObject, public QScriptable, public Dependency {
|
class GraphicsScriptingInterface : public QObject, public QScriptable, public Dependency {
|
||||||
|
|
|
@ -5,3 +5,4 @@ link_hifi_libraries(shared)
|
||||||
|
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(graphics)
|
include_hifi_library_headers(graphics)
|
||||||
|
include_hifi_library_headers(image)
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <graphics/Geometry.h>
|
#include <graphics/Geometry.h>
|
||||||
#include <graphics/Material.h>
|
#include <graphics/Material.h>
|
||||||
|
|
||||||
|
#include <image/ColorChannel.h>
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
#define HFM_PACK_NORMALS 0
|
#define HFM_PACK_NORMALS 0
|
||||||
#else
|
#else
|
||||||
|
@ -119,10 +121,12 @@ public:
|
||||||
/// A texture map.
|
/// A texture map.
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
QString id;
|
QString id;
|
||||||
QString name;
|
QString name;
|
||||||
QByteArray filename;
|
QByteArray filename;
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
|
image::ColorChannel sourceChannel { image::ColorChannel::NONE };
|
||||||
|
|
||||||
Transform transform;
|
Transform transform;
|
||||||
int maxNumPixels { MAX_NUM_PIXELS_FOR_FBX_TEXTURE };
|
int maxNumPixels { MAX_NUM_PIXELS_FOR_FBX_TEXTURE };
|
||||||
|
|
26
libraries/image/src/image/ColorChannel.h
Normal file
26
libraries/image/src/image/ColorChannel.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// ColorChannel.h
|
||||||
|
// libraries/image/src/image
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman on 2019/02/12.
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_image_ColorChannel_h
|
||||||
|
#define hifi_image_ColorChannel_h
|
||||||
|
|
||||||
|
namespace image {
|
||||||
|
enum class ColorChannel {
|
||||||
|
NONE,
|
||||||
|
RED,
|
||||||
|
GREEN,
|
||||||
|
BLUE,
|
||||||
|
ALPHA,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_image_ColorChannel_h
|
|
@ -16,6 +16,7 @@
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <QRgb>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
|
||||||
|
@ -221,7 +222,45 @@ QImage processRawImageData(QIODevice& content, const std::string& filename) {
|
||||||
return QImage();
|
return QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& filename,
|
void mapToRedChannel(QImage& image, ColorChannel sourceChannel) {
|
||||||
|
// Change format of image so we know exactly how to process it
|
||||||
|
if (image.format() != QImage::Format_ARGB32) {
|
||||||
|
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < image.height(); i++) {
|
||||||
|
QRgb* pixel = reinterpret_cast<QRgb*>(image.scanLine(i));
|
||||||
|
// Past end pointer
|
||||||
|
QRgb* lineEnd = pixel + image.width();
|
||||||
|
|
||||||
|
// Transfer channel data from source to target
|
||||||
|
for (; pixel < lineEnd; pixel++) {
|
||||||
|
int colorValue;
|
||||||
|
switch (sourceChannel) {
|
||||||
|
case ColorChannel::RED:
|
||||||
|
colorValue = qRed(*pixel);
|
||||||
|
break;
|
||||||
|
case ColorChannel::GREEN:
|
||||||
|
colorValue = qGreen(*pixel);
|
||||||
|
break;
|
||||||
|
case ColorChannel::BLUE:
|
||||||
|
colorValue = qBlue(*pixel);
|
||||||
|
break;
|
||||||
|
case ColorChannel::ALPHA:
|
||||||
|
colorValue = qAlpha(*pixel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
colorValue = qRed(*pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump the color in the red channel, ignore the rest
|
||||||
|
*pixel = qRgba(colorValue, 0, 0, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& filename, ColorChannel sourceChannel,
|
||||||
int maxNumPixels, TextureUsage::Type textureType,
|
int maxNumPixels, TextureUsage::Type textureType,
|
||||||
bool compress, BackendTarget target, const std::atomic<bool>& abortProcessing) {
|
bool compress, BackendTarget target, const std::atomic<bool>& abortProcessing) {
|
||||||
|
|
||||||
|
@ -252,6 +291,11 @@ gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::
|
||||||
QSize(originalWidth, originalHeight) << " to " <<
|
QSize(originalWidth, originalHeight) << " to " <<
|
||||||
QSize(imageWidth, imageHeight) << ")";
|
QSize(imageWidth, imageHeight) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-map to image with single red channel texture if requested
|
||||||
|
if (sourceChannel != ColorChannel::NONE) {
|
||||||
|
mapToRedChannel(image, sourceChannel);
|
||||||
|
}
|
||||||
|
|
||||||
auto loader = TextureUsage::getTextureLoaderForType(textureType);
|
auto loader = TextureUsage::getTextureLoaderForType(textureType);
|
||||||
auto texture = loader(std::move(image), filename, compress, target, abortProcessing);
|
auto texture = loader(std::move(image), filename, compress, target, abortProcessing);
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <gpu/Texture.h>
|
#include <gpu/Texture.h>
|
||||||
|
|
||||||
|
#include "ColorChannel.h"
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QImage;
|
class QImage;
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ gpu::TexturePointer processCubeTextureColorFromImage(QImage&& srcImage, const st
|
||||||
|
|
||||||
const QStringList getSupportedFormats();
|
const QStringList getSupportedFormats();
|
||||||
|
|
||||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url,
|
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url, ColorChannel sourceChannel,
|
||||||
int maxNumPixels, TextureUsage::Type textureType,
|
int maxNumPixels, TextureUsage::Type textureType,
|
||||||
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing = false);
|
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing = false);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Midi : public QObject, public Dependency {
|
class Midi : public QObject, public Dependency {
|
||||||
|
|
|
@ -2,3 +2,5 @@ set(TARGET_NAME model-baker)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
|
|
||||||
link_hifi_libraries(shared task gpu graphics hfm)
|
link_hifi_libraries(shared task gpu graphics hfm)
|
||||||
|
|
||||||
|
include_hifi_library_headers(image)
|
||||||
|
|
|
@ -322,7 +322,7 @@ private:
|
||||||
void GeometryDefinitionResource::setExtra(void* extra) {
|
void GeometryDefinitionResource::setExtra(void* extra) {
|
||||||
const GeometryExtra* geometryExtra = static_cast<const GeometryExtra*>(extra);
|
const GeometryExtra* geometryExtra = static_cast<const GeometryExtra*>(extra);
|
||||||
_mapping = geometryExtra ? geometryExtra->mapping : QVariantHash();
|
_mapping = geometryExtra ? geometryExtra->mapping : QVariantHash();
|
||||||
_textureBaseUrl = resolveTextureBaseUrl(_url, geometryExtra ? geometryExtra->textureBaseUrl : QUrl());
|
_textureBaseUrl = geometryExtra ? resolveTextureBaseUrl(_url, geometryExtra->textureBaseUrl) : QUrl();
|
||||||
_combineParts = geometryExtra ? geometryExtra->combineParts : true;
|
_combineParts = geometryExtra ? geometryExtra->combineParts : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
||||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
|
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels, hfmTexture.sourceChannel);
|
||||||
_textures[channel] = Texture { hfmTexture.name, texture };
|
_textures[channel] = Texture { hfmTexture.name, texture };
|
||||||
|
|
||||||
auto map = std::make_shared<graphics::TextureMap>();
|
auto map = std::make_shared<graphics::TextureMap>();
|
||||||
|
|
|
@ -30,6 +30,7 @@ class ModelCacheScriptingInterface : public ScriptableResourceCache, public Depe
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||||
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
||||||
|
|
|
@ -192,6 +192,7 @@ public:
|
||||||
image::TextureUsage::Type type;
|
image::TextureUsage::Type type;
|
||||||
const QByteArray& content;
|
const QByteArray& content;
|
||||||
int maxNumPixels;
|
int maxNumPixels;
|
||||||
|
image::ColorChannel sourceChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
@ -206,19 +207,19 @@ namespace std {
|
||||||
struct hash<TextureExtra> {
|
struct hash<TextureExtra> {
|
||||||
size_t operator()(const TextureExtra& a) const {
|
size_t operator()(const TextureExtra& a) const {
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
hash_combine(result, (int)a.type, a.content, a.maxNumPixels);
|
hash_combine(result, (int)a.type, a.content, a.maxNumPixels, (int)a.sourceChannel);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxNumPixels) {
|
ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxNumPixels, image::ColorChannel sourceChannel) {
|
||||||
auto byteArray = QByteArray();
|
auto byteArray = QByteArray();
|
||||||
TextureExtra extra = { (image::TextureUsage::Type)type, byteArray, maxNumPixels };
|
TextureExtra extra = { (image::TextureUsage::Type)type, byteArray, maxNumPixels, sourceChannel };
|
||||||
return ResourceCache::prefetch(url, &extra, std::hash<TextureExtra>()(extra));
|
return ResourceCache::prefetch(url, &extra, std::hash<TextureExtra>()(extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels) {
|
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels, image::ColorChannel sourceChannel) {
|
||||||
if (url.scheme() == RESOURCE_SCHEME) {
|
if (url.scheme() == RESOURCE_SCHEME) {
|
||||||
return getResourceTexture(url);
|
return getResourceTexture(url);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +229,7 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUs
|
||||||
query.addQueryItem("skybox", "");
|
query.addQueryItem("skybox", "");
|
||||||
modifiedUrl.setQuery(query.toString());
|
modifiedUrl.setQuery(query.toString());
|
||||||
}
|
}
|
||||||
TextureExtra extra = { type, content, maxNumPixels };
|
TextureExtra extra = { type, content, maxNumPixels, sourceChannel };
|
||||||
return ResourceCache::getResource(modifiedUrl, QUrl(), &extra, std::hash<TextureExtra>()(extra)).staticCast<NetworkTexture>();
|
return ResourceCache::getResource(modifiedUrl, QUrl(), &extra, std::hash<TextureExtra>()(extra)).staticCast<NetworkTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +336,7 @@ int networkTexturePointerMetaTypeId = qRegisterMetaType<QWeakPointer<NetworkText
|
||||||
|
|
||||||
NetworkTexture::NetworkTexture(const QUrl& url, bool resourceTexture) :
|
NetworkTexture::NetworkTexture(const QUrl& url, bool resourceTexture) :
|
||||||
Resource(url),
|
Resource(url),
|
||||||
|
Texture(),
|
||||||
_maxNumPixels(100)
|
_maxNumPixels(100)
|
||||||
{
|
{
|
||||||
if (resourceTexture) {
|
if (resourceTexture) {
|
||||||
|
@ -345,7 +347,9 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool resourceTexture) :
|
||||||
|
|
||||||
NetworkTexture::NetworkTexture(const NetworkTexture& other) :
|
NetworkTexture::NetworkTexture(const NetworkTexture& other) :
|
||||||
Resource(other),
|
Resource(other),
|
||||||
|
Texture(other),
|
||||||
_type(other._type),
|
_type(other._type),
|
||||||
|
_sourceChannel(other._sourceChannel),
|
||||||
_currentlyLoadingResourceType(other._currentlyLoadingResourceType),
|
_currentlyLoadingResourceType(other._currentlyLoadingResourceType),
|
||||||
_originalWidth(other._originalWidth),
|
_originalWidth(other._originalWidth),
|
||||||
_originalHeight(other._originalHeight),
|
_originalHeight(other._originalHeight),
|
||||||
|
@ -353,6 +357,11 @@ NetworkTexture::NetworkTexture(const NetworkTexture& other) :
|
||||||
_height(other._height),
|
_height(other._height),
|
||||||
_maxNumPixels(other._maxNumPixels)
|
_maxNumPixels(other._maxNumPixels)
|
||||||
{
|
{
|
||||||
|
if (_width == 0 || _height == 0 ||
|
||||||
|
other._currentlyLoadingResourceType == ResourceType::META ||
|
||||||
|
(other._currentlyLoadingResourceType == ResourceType::KTX && other._ktxResourceState != KTXResourceState::WAITING_FOR_MIP_REQUEST)) {
|
||||||
|
_startedLoading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isLocalUrl(const QUrl& url) {
|
static bool isLocalUrl(const QUrl& url) {
|
||||||
|
@ -364,8 +373,14 @@ void NetworkTexture::setExtra(void* extra) {
|
||||||
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
|
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
|
||||||
_type = textureExtra ? textureExtra->type : image::TextureUsage::DEFAULT_TEXTURE;
|
_type = textureExtra ? textureExtra->type : image::TextureUsage::DEFAULT_TEXTURE;
|
||||||
_maxNumPixels = textureExtra ? textureExtra->maxNumPixels : ABSOLUTE_MAX_TEXTURE_NUM_PIXELS;
|
_maxNumPixels = textureExtra ? textureExtra->maxNumPixels : ABSOLUTE_MAX_TEXTURE_NUM_PIXELS;
|
||||||
|
_sourceChannel = textureExtra ? textureExtra->sourceChannel : image::ColorChannel::NONE;
|
||||||
|
|
||||||
_textureSource = std::make_shared<gpu::TextureSource>(_url, (int)_type);
|
if (_textureSource) {
|
||||||
|
_textureSource->setUrl(_url);
|
||||||
|
_textureSource->setType((int)_type);
|
||||||
|
} else {
|
||||||
|
_textureSource = std::make_shared<gpu::TextureSource>(_url, (int)_type);
|
||||||
|
}
|
||||||
_lowestRequestedMipLevel = 0;
|
_lowestRequestedMipLevel = 0;
|
||||||
|
|
||||||
auto fileNameLowercase = _url.fileName().toLower();
|
auto fileNameLowercase = _url.fileName().toLower();
|
||||||
|
@ -425,7 +440,8 @@ gpu::TexturePointer NetworkTexture::getFallbackTexture() const {
|
||||||
class ImageReader : public QRunnable {
|
class ImageReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url,
|
ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url,
|
||||||
const QByteArray& data, size_t extraHash, int maxNumPixels);
|
const QByteArray& data, size_t extraHash, int maxNumPixels,
|
||||||
|
image::ColorChannel sourceChannel);
|
||||||
void run() override final;
|
void run() override final;
|
||||||
void read();
|
void read();
|
||||||
|
|
||||||
|
@ -437,6 +453,7 @@ private:
|
||||||
QByteArray _content;
|
QByteArray _content;
|
||||||
size_t _extraHash;
|
size_t _extraHash;
|
||||||
int _maxNumPixels;
|
int _maxNumPixels;
|
||||||
|
image::ColorChannel _sourceChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkTexture::~NetworkTexture() {
|
NetworkTexture::~NetworkTexture() {
|
||||||
|
@ -523,7 +540,6 @@ void NetworkTexture::makeRequest() {
|
||||||
} else {
|
} else {
|
||||||
qWarning(networking) << "NetworkTexture::makeRequest() called while not in a valid state: " << _ktxResourceState;
|
qWarning(networking) << "NetworkTexture::makeRequest() called while not in a valid state: " << _ktxResourceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::handleLocalRequestCompleted() {
|
void NetworkTexture::handleLocalRequestCompleted() {
|
||||||
|
@ -1069,7 +1085,7 @@ void NetworkTexture::loadTextureContent(const QByteArray& content) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QThreadPool::globalInstance()->start(new ImageReader(_self, _url, content, _extraHash, _maxNumPixels));
|
QThreadPool::globalInstance()->start(new ImageReader(_self, _url, content, _extraHash, _maxNumPixels, _sourceChannel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::refresh() {
|
void NetworkTexture::refresh() {
|
||||||
|
@ -1094,12 +1110,13 @@ void NetworkTexture::refresh() {
|
||||||
Resource::refresh();
|
Resource::refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url, const QByteArray& data, size_t extraHash, int maxNumPixels) :
|
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url, const QByteArray& data, size_t extraHash, int maxNumPixels, image::ColorChannel sourceChannel) :
|
||||||
_resource(resource),
|
_resource(resource),
|
||||||
_url(url),
|
_url(url),
|
||||||
_content(data),
|
_content(data),
|
||||||
_extraHash(extraHash),
|
_extraHash(extraHash),
|
||||||
_maxNumPixels(maxNumPixels)
|
_maxNumPixels(maxNumPixels),
|
||||||
|
_sourceChannel(sourceChannel)
|
||||||
{
|
{
|
||||||
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||||
listSupportedImageFormats();
|
listSupportedImageFormats();
|
||||||
|
@ -1207,7 +1224,7 @@ void ImageReader::read() {
|
||||||
constexpr bool shouldCompress = false;
|
constexpr bool shouldCompress = false;
|
||||||
#endif
|
#endif
|
||||||
auto target = getBackendTarget();
|
auto target = getBackendTarget();
|
||||||
texture = image::processImage(std::move(buffer), _url.toString().toStdString(), _maxNumPixels, networkTexture->getTextureType(), shouldCompress, target);
|
texture = image::processImage(std::move(buffer), _url.toString().toStdString(), _sourceChannel, _maxNumPixels, networkTexture->getTextureType(), shouldCompress, target);
|
||||||
|
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
QMetaObject::invokeMethod(resource.data(), "setImage",
|
QMetaObject::invokeMethod(resource.data(), "setImage",
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
#include <graphics/TextureMap.h>
|
#include <graphics/TextureMap.h>
|
||||||
|
#include <image/ColorChannel.h>
|
||||||
#include <image/Image.h>
|
#include <image/Image.h>
|
||||||
#include <ktx/KTX.h>
|
#include <ktx/KTX.h>
|
||||||
#include <TextureMeta.h>
|
#include <TextureMeta.h>
|
||||||
|
@ -96,6 +97,7 @@ private:
|
||||||
friend class ImageReader;
|
friend class ImageReader;
|
||||||
|
|
||||||
image::TextureUsage::Type _type;
|
image::TextureUsage::Type _type;
|
||||||
|
image::ColorChannel _sourceChannel;
|
||||||
|
|
||||||
enum class ResourceType {
|
enum class ResourceType {
|
||||||
META,
|
META,
|
||||||
|
@ -178,7 +180,8 @@ public:
|
||||||
|
|
||||||
/// Loads a texture from the specified URL.
|
/// Loads a texture from the specified URL.
|
||||||
NetworkTexturePointer getTexture(const QUrl& url, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE,
|
NetworkTexturePointer getTexture(const QUrl& url, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE,
|
||||||
const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);
|
const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS,
|
||||||
|
image::ColorChannel sourceChannel = image::ColorChannel::NONE);
|
||||||
|
|
||||||
gpu::TexturePointer getTextureByHash(const std::string& hash);
|
gpu::TexturePointer getTextureByHash(const std::string& hash);
|
||||||
gpu::TexturePointer cacheTextureByHash(const std::string& hash, const gpu::TexturePointer& texture);
|
gpu::TexturePointer cacheTextureByHash(const std::string& hash, const gpu::TexturePointer& texture);
|
||||||
|
@ -201,7 +204,7 @@ signals:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Overload ResourceCache::prefetch to allow specifying texture type for loads
|
// Overload ResourceCache::prefetch to allow specifying texture type for loads
|
||||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);
|
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, image::ColorChannel sourceChannel = image::ColorChannel::NONE);
|
||||||
|
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
|
virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
|
||||||
QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
|
QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
|
||||||
|
|
|
@ -30,6 +30,7 @@ class TextureCacheScriptingInterface : public ScriptableResourceCache, public De
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||||
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
||||||
|
|
|
@ -43,6 +43,7 @@ const QString GET_PLACE = "/api/v1/places/%1";
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
* @property {Uuid} domainID - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid|Uuid.NULL} if you're not
|
* @property {Uuid} domainID - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid|Uuid.NULL} if you're not
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -362,7 +362,6 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
resource->moveToThread(qApp->thread());
|
resource->moveToThread(qApp->thread());
|
||||||
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
|
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
|
||||||
resourcesWithExtraHash.insert(extraHash, resource);
|
resourcesWithExtraHash.insert(extraHash, resource);
|
||||||
removeUnusedResource(resource);
|
|
||||||
resource->ensureLoading();
|
resource->ensureLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,7 +403,7 @@ void ResourceCache::addUnusedResource(const QSharedPointer<Resource>& resource)
|
||||||
// If it doesn't fit or its size is unknown, remove it from the cache.
|
// If it doesn't fit or its size is unknown, remove it from the cache.
|
||||||
if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) {
|
if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) {
|
||||||
resource->setCache(nullptr);
|
resource->setCache(nullptr);
|
||||||
removeResource(resource->getURL(), resource->getBytes());
|
removeResource(resource->getURL(), resource->getExtraHash(), resource->getBytes());
|
||||||
resetTotalResourceCounter();
|
resetTotalResourceCounter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +442,7 @@ void ResourceCache::reserveUnusedResource(qint64 resourceSize) {
|
||||||
auto size = it.value()->getBytes();
|
auto size = it.value()->getBytes();
|
||||||
|
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
removeResource(it.value()->getURL(), size);
|
removeResource(it.value()->getURL(), it.value()->getExtraHash(), size);
|
||||||
locker.relock();
|
locker.relock();
|
||||||
|
|
||||||
_unusedResourcesSize -= size;
|
_unusedResourcesSize -= size;
|
||||||
|
@ -489,9 +488,13 @@ void ResourceCache::resetResourceCounters() {
|
||||||
emit dirty();
|
emit dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::removeResource(const QUrl& url, qint64 size) {
|
void ResourceCache::removeResource(const QUrl& url, size_t extraHash, qint64 size) {
|
||||||
QWriteLocker locker(&_resourcesLock);
|
QWriteLocker locker(&_resourcesLock);
|
||||||
_resources.remove(url);
|
auto& resources = _resources[url];
|
||||||
|
resources.remove(extraHash);
|
||||||
|
if (resources.size() == 0) {
|
||||||
|
_resources.remove(url);
|
||||||
|
}
|
||||||
_totalResourcesSize -= size;
|
_totalResourcesSize -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +667,7 @@ void Resource::allReferencesCleared() {
|
||||||
} else {
|
} else {
|
||||||
if (_cache) {
|
if (_cache) {
|
||||||
// remove from the cache
|
// remove from the cache
|
||||||
_cache->removeResource(getURL(), getBytes());
|
_cache->removeResource(getURL(), getExtraHash(), getBytes());
|
||||||
_cache->resetTotalResourceCounter();
|
_cache->resetTotalResourceCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ class ScriptableResource : public QObject {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
@ -271,7 +272,7 @@ private:
|
||||||
friend class ScriptableResourceCache;
|
friend class ScriptableResourceCache;
|
||||||
|
|
||||||
void reserveUnusedResource(qint64 resourceSize);
|
void reserveUnusedResource(qint64 resourceSize);
|
||||||
void removeResource(const QUrl& url, qint64 size = 0);
|
void removeResource(const QUrl& url, size_t extraHash, qint64 size = 0);
|
||||||
|
|
||||||
void resetTotalResourceCounter();
|
void resetTotalResourceCounter();
|
||||||
void resetUnusedResourceCounter();
|
void resetUnusedResourceCounter();
|
||||||
|
@ -418,6 +419,7 @@ public:
|
||||||
|
|
||||||
virtual void setExtra(void* extra) {};
|
virtual void setExtra(void* extra) {};
|
||||||
void setExtraHash(size_t extraHash) { _extraHash = extraHash; }
|
void setExtraHash(size_t extraHash) { _extraHash = extraHash; }
|
||||||
|
size_t getExtraHash() const { return _extraHash; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/// Fired when the resource begins downloading.
|
/// Fired when the resource begins downloading.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {boolean} running - <em>Read-only.</em>
|
* @property {boolean} running - <em>Read-only.</em>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -68,6 +68,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {number} Ray Ray picks intersect a ray with the nearest object in front of them, along a given direction.
|
* @property {number} Ray Ray picks intersect a ray with the nearest object in front of them, along a given direction.
|
||||||
* @property {number} Stylus Stylus picks provide "tapping" functionality on/into flat surfaces.
|
* @property {number} Stylus Stylus picks provide "tapping" functionality on/into flat surfaces.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
set(TARGET_NAME procedural)
|
set(TARGET_NAME procedural)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared gpu shaders networking graphics model-networking ktx image)
|
link_hifi_libraries(shared gpu shaders networking graphics model-networking ktx image)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -28,6 +28,7 @@ class QScriptValue;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*/
|
*/
|
||||||
class RecordingScriptingInterface : public QObject, public Dependency {
|
class RecordingScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace SceneScripting {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {string} backgroundMode
|
* @property {string} backgroundMode
|
||||||
* @property {Scene.Stage.KeyLight} keyLight
|
* @property {Scene.Stage.KeyLight} keyLight
|
||||||
|
@ -178,6 +179,7 @@ namespace SceneScripting {
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {boolean} shouldRenderAvatars
|
* @property {boolean} shouldRenderAvatars
|
||||||
* @property {boolean} shouldRenderEntities
|
* @property {boolean} shouldRenderEntities
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -588,6 +588,7 @@ static void scriptableResourceFromScriptValue(const QScriptValue& value, Scripta
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -104,6 +104,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,6 +32,7 @@ class ScriptEngine;
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*
|
*
|
||||||
* @property {string} debugScriptUrl
|
* @property {string} debugScriptUrl
|
||||||
* @property {string} defaultScriptsPath
|
* @property {string} defaultScriptsPath
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
* @hifi-server-entity
|
* @hifi-server-entity
|
||||||
* @hifi-assignment-client
|
* @hifi-assignment-client
|
||||||
*
|
*
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
|
* @hifi-avatar
|
||||||
*/
|
*/
|
||||||
class ScriptsModel : public QAbstractItemModel {
|
class ScriptsModel : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue