mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:49:24 +02:00
Merge branch 'master' into editHandlePickPlaneImprovements
This commit is contained in:
commit
b5edf42fd0
133 changed files with 1856 additions and 399 deletions
|
@ -133,6 +133,10 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
implementation 'com.android.support:design:26.1.0'
|
implementation 'com.android.support:design:26.1.0'
|
||||||
|
compile 'com.android.support:support-v4:26.1.0'
|
||||||
|
compile 'com.android.support:appcompat-v7:26.1.0'
|
||||||
|
compile 'com.android.support:support-vector-drawable:26.1.0'
|
||||||
|
|
||||||
implementation 'com.android.support:appcompat-v7:26.1.0'
|
implementation 'com.android.support:appcompat-v7:26.1.0'
|
||||||
compile 'com.android.support:recyclerview-v7:26.1.0'
|
compile 'com.android.support:recyclerview-v7:26.1.0'
|
||||||
compile 'com.android.support:cardview-v7:26.1.0'
|
compile 'com.android.support:cardview-v7:26.1.0'
|
||||||
|
|
|
@ -255,6 +255,16 @@ JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_fragment_HomeFragme
|
||||||
return env->NewStringUTF(lastLocation.toString().toLatin1().data());
|
return env->NewStringUTF(lastLocation.toString().toLatin1().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(JNIEnv *env, jobject instance) {
|
||||||
|
|
||||||
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
||||||
|
QObject::disconnect(accountManager.data(), &AccountManager::loginComplete, nullptr, nullptr);
|
||||||
|
QObject::disconnect(accountManager.data(), &AccountManager::loginFailed, nullptr, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *env, jobject instance,
|
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *env, jobject instance,
|
||||||
jstring username_, jstring password_,
|
jstring username_, jstring password_,
|
||||||
|
@ -273,17 +283,23 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
|
||||||
|
|
||||||
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
|
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
|
||||||
jboolean jSuccess = (jboolean) true;
|
jboolean jSuccess = (jboolean) true;
|
||||||
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
if (__loginCompletedListener.isValid()) {
|
||||||
|
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() {
|
QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() {
|
||||||
jboolean jSuccess = (jboolean) false;
|
jboolean jSuccess = (jboolean) false;
|
||||||
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
if (__loginCompletedListener.isValid()) {
|
||||||
|
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) {
|
QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) {
|
||||||
QAndroidJniObject string = QAndroidJniObject::fromString(username);
|
QAndroidJniObject string = QAndroidJniObject::fromString(username);
|
||||||
__usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
|
if (__usernameChangedListener.isValid()) {
|
||||||
|
__usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken",
|
QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken",
|
||||||
|
|
|
@ -4,12 +4,10 @@ import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -19,8 +17,13 @@ import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.qtproject.qt5.android.QtNative;
|
||||||
|
|
||||||
import io.highfidelity.hifiinterface.R;
|
import io.highfidelity.hifiinterface.R;
|
||||||
|
|
||||||
|
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationActive;
|
||||||
|
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationInactive;
|
||||||
|
|
||||||
public class LoginFragment extends Fragment {
|
public class LoginFragment extends Fragment {
|
||||||
|
|
||||||
private EditText mUsername;
|
private EditText mUsername;
|
||||||
|
@ -32,6 +35,7 @@ public class LoginFragment extends Fragment {
|
||||||
private ProgressDialog mDialog;
|
private ProgressDialog mDialog;
|
||||||
|
|
||||||
public native void nativeLogin(String username, String password, Activity usernameChangedListener);
|
public native void nativeLogin(String username, String password, Activity usernameChangedListener);
|
||||||
|
public native void nativeCancelLogin();
|
||||||
|
|
||||||
private LoginFragment.OnLoginInteractionListener mListener;
|
private LoginFragment.OnLoginInteractionListener mListener;
|
||||||
|
|
||||||
|
@ -55,44 +59,6 @@ public class LoginFragment extends Fragment {
|
||||||
mLoginButton = rootView.findViewById(R.id.loginButton);
|
mLoginButton = rootView.findViewById(R.id.loginButton);
|
||||||
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
|
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
|
||||||
|
|
||||||
mUsername.addTextChangedListener(new TextWatcher() {
|
|
||||||
boolean ignoreNextChange = false;
|
|
||||||
boolean hadBlankSpace = false;
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
|
|
||||||
hadBlankSpace = charSequence.length() > 0 && charSequence.charAt(charSequence.length()-1) == ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int start, int count, int after) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
if (!ignoreNextChange) {
|
|
||||||
ignoreNextChange = true;
|
|
||||||
boolean spaceFound = false;
|
|
||||||
for (int i = 0; i < editable.length(); i++) {
|
|
||||||
if (editable.charAt(i) == ' ') {
|
|
||||||
spaceFound=true;
|
|
||||||
editable.delete(i, i + 1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hadBlankSpace && !spaceFound && editable.length() > 0) {
|
|
||||||
editable.delete(editable.length()-1, editable.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
editable.append(' ');
|
|
||||||
ignoreNextChange = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
mLoginButton.setOnClickListener(view -> login());
|
mLoginButton.setOnClickListener(view -> login());
|
||||||
|
|
||||||
mForgotPassword.setOnClickListener(view -> forgotPassword());
|
mForgotPassword.setOnClickListener(view -> forgotPassword());
|
||||||
|
@ -125,10 +91,19 @@ public class LoginFragment extends Fragment {
|
||||||
mListener = null;
|
mListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
// This hack intends to keep Qt threads running even after the app comes from background
|
||||||
|
QtNative.setApplicationState(ApplicationActive);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
cancelActivityIndicator();
|
cancelActivityIndicator();
|
||||||
|
// Leave the Qt app paused
|
||||||
|
QtNative.setApplicationState(ApplicationInactive);
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +139,15 @@ public class LoginFragment extends Fragment {
|
||||||
mDialog = new ProgressDialog(getContext());
|
mDialog = new ProgressDialog(getContext());
|
||||||
}
|
}
|
||||||
mDialog.setMessage(getString(R.string.logging_in));
|
mDialog.setMessage(getString(R.string.logging_in));
|
||||||
mDialog.setCancelable(false);
|
mDialog.setCancelable(true);
|
||||||
|
mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialogInterface) {
|
||||||
|
nativeCancelLogin();
|
||||||
|
cancelActivityIndicator();
|
||||||
|
mLoginButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
mDialog.show();
|
mDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +167,6 @@ public class LoginFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleLoginCompleted(boolean success) {
|
public void handleLoginCompleted(boolean success) {
|
||||||
Log.d("[LOGIN]", "handleLoginCompleted " + success);
|
|
||||||
getActivity().runOnUiThread(() -> {
|
getActivity().runOnUiThread(() -> {
|
||||||
mLoginButton.setEnabled(true);
|
mLoginButton.setEnabled(true);
|
||||||
cancelActivityIndicator();
|
cancelActivityIndicator();
|
||||||
|
|
27
android/app/src/main/res/drawable/ic_eye_noshow.xml
Normal file
27
android/app/src/main/res/drawable/ic_eye_noshow.xml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="22dp"
|
||||||
|
android:viewportWidth="36"
|
||||||
|
android:viewportHeight="22">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#3D3D3D"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M3.59534,11.0156 C6.16042,13.4128,9.65987,15.5898,13.6042,16.1774 C17.686,16.7856,22.4164,15.7196,27.3057,11.0659 C22.0721,6.07309,17.0642,5.14115,12.9153,5.90073 C8.99427,6.61859,5.69298,8.87688,3.59534,11.0156 Z M12.455,3.27591 C17.7727,2.30235,23.9836,3.74895,30.1053,10.1333 L31,11.0664 L30.1053,11.9994 C24.3636,17.9875,18.4774,19.5983,13.2276,18.8161 C8.06048,18.0463,3.70384,14.9892,0.837069,11.9994 L0,11.1265 L0.778477,10.1986 C3.05338,7.48717,7.2318,4.23217,12.455,3.27591 Z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#3D3D3D"
|
||||||
|
android:pathData="M15.6539,7.11119 C17.6719,7.11119,19.3078,8.81726,19.3078,10.9218 C19.3078,13.0263,17.6719,14.7324,15.6539,14.7324 C13.6359,14.7324,12,13.0263,12,10.9218 C12,8.81726,13.6359,7.11119,15.6539,7.11119 Z" />
|
||||||
|
<!--path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeWidth="2.7"
|
||||||
|
android:strokeLineCap="round"
|
||||||
|
android:pathData="M27,2.90919 L8.90919,21" /-->
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:strokeColor="#3D3D3D"
|
||||||
|
android:strokeWidth="3"
|
||||||
|
android:strokeLineCap="round"
|
||||||
|
android:pathData="M25,2.12132 L7.12132,20" />
|
||||||
|
</vector>
|
15
android/app/src/main/res/drawable/ic_eye_show.xml
Normal file
15
android/app/src/main/res/drawable/ic_eye_show.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="16dp"
|
||||||
|
android:viewportWidth="36"
|
||||||
|
android:viewportHeight="16">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#3D3D3D"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M3.59534,8.01564 C6.16042,10.4128,9.65987,12.5898,13.6042,13.1774 C17.686,13.7856,22.4164,12.7196,27.3057,8.06585 C22.0721,3.07309,17.0642,2.14115,12.9153,2.90073 C8.99427,3.61859,5.69298,5.87688,3.59534,8.01564 Z M12.455,0.275915 C17.7727,-0.697651,23.9836,0.748949,30.1053,7.13329 L31,8.06636 L30.1053,8.99944 C24.3636,14.9875,18.4774,16.5983,13.2276,15.8161 C8.06048,15.0463,3.70384,11.9892,0.837069,8.99944 L0,8.12646 L0.778477,7.1986 C3.05338,4.48717,7.2318,1.23217,12.455,0.275915 Z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#3D3D3D"
|
||||||
|
android:pathData="M15.6441,4.11118 C17.6621,4.11118,19.298,5.81725,19.298,7.92179 C19.298,10.0263,17.6621,11.7324,15.6441,11.7324 C13.6261,11.7324,11.9902,10.0263,11.9902,7.92179 C11.9902,5.81725,13.6261,4.11118,15.6441,4.11118 Z" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_checked="true" android:drawable="@drawable/ic_eye_noshow"/>
|
||||||
|
<item android:drawable="@drawable/ic_eye_show" />
|
||||||
|
</selector>
|
|
@ -41,38 +41,51 @@
|
||||||
android:paddingTop="14dp"
|
android:paddingTop="14dp"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:fontFamily="@font/raleway"
|
android:fontFamily="@font/raleway"
|
||||||
android:textSize="14sp"
|
android:textSize="17sp"
|
||||||
android:inputType="textEmailAddress"
|
android:inputType="textEmailAddress"
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
android:textColor="@color/editTextColor"
|
android:textColor="@color/editTextColor"
|
||||||
android:textColorHint="@color/editTextColor"
|
android:textColorHint="@color/editTextColor"
|
||||||
android:gravity="right|center_vertical"
|
android:gravity="left|center_vertical"
|
||||||
app:layout_constraintTop_toBottomOf="@id/header"
|
app:layout_constraintTop_toBottomOf="@id/header"
|
||||||
android:layout_marginTop="70dp"
|
android:layout_marginTop="70dp"
|
||||||
android:hint="@string/username_or_email" />
|
android:hint="@string/username_or_email" />
|
||||||
|
|
||||||
<EditText
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/passwordLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="46dp"
|
||||||
|
android:layout_marginRight="46dp"
|
||||||
|
app:passwordToggleTint="@color/showPasswordColor"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
app:hintAnimationEnabled="false"
|
||||||
|
app:passwordToggleDrawable="@drawable/selector_show_password"
|
||||||
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/username"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
>
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
android:id="@+id/password"
|
android:id="@+id/password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_marginLeft="46dp"
|
|
||||||
android:layout_marginRight="46dp"
|
|
||||||
android:background="@drawable/rounded_edit"
|
android:background="@drawable/rounded_edit"
|
||||||
android:padding="7dp"
|
android:padding="7dp"
|
||||||
android:paddingRight="12dp"
|
android:drawablePadding="55dp"
|
||||||
android:paddingTop="14dp"
|
android:paddingTop="14dp"
|
||||||
|
android:drawableEnd="@drawable/ic_eye_noshow"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:fontFamily="@font/raleway"
|
android:fontFamily="@font/raleway"
|
||||||
android:textSize="14sp"
|
android:textSize="17sp"
|
||||||
android:inputType="textPassword"
|
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
android:textColor="@color/editTextColor"
|
android:textColor="@color/editTextColor"
|
||||||
android:textColorHint="@color/editTextColor"
|
android:textColorHint="@color/editTextColor"
|
||||||
android:gravity="right|center_vertical"
|
android:gravity="left|center_vertical"
|
||||||
app:layout_constraintTop_toBottomOf="@id/username"
|
android:imeOptions="actionDone"
|
||||||
android:hint="@string/password"
|
android:hint="@string/password"
|
||||||
android:layout_marginTop="13dp"
|
android:inputType="textPassword" />
|
||||||
android:imeOptions="actionDone"/>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/loginButton"
|
android:id="@+id/loginButton"
|
||||||
|
@ -90,7 +103,7 @@
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintRight_toRightOf="@id/username"
|
app:layout_constraintRight_toRightOf="@id/username"
|
||||||
app:layout_constraintTop_toBottomOf="@id/password"
|
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||||
app:layout_goneMarginTop="4dp"/>
|
app:layout_goneMarginTop="4dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -102,7 +115,7 @@
|
||||||
android:text="@string/forgot_password"
|
android:text="@string/forgot_password"
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
android:paddingRight="10dp"
|
android:paddingRight="10dp"
|
||||||
app:layout_constraintLeft_toLeftOf="@id/password"
|
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||||
app:layout_constraintTop_toTopOf="@id/loginButton"
|
app:layout_constraintTop_toTopOf="@id/loginButton"
|
||||||
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||||
android:textColor="@color/colorButton1"/>
|
android:textColor="@color/colorButton1"/>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<color name="colorAccent">#54D7FD</color>
|
<color name="colorAccent">#54D7FD</color>
|
||||||
<color name="backgroundEditText">#E3E3E3</color>
|
<color name="backgroundEditText">#E3E3E3</color>
|
||||||
<color name="editTextColor">#575757</color>
|
<color name="editTextColor">#575757</color>
|
||||||
|
<color name="showPasswordColor">#3D3D3D</color>
|
||||||
<color name="tabs">#1EB5EC</color>
|
<color name="tabs">#1EB5EC</color>
|
||||||
<color name="colorButton1">#00B4EF</color>
|
<color name="colorButton1">#00B4EF</color>
|
||||||
<color name="backgroundDark">#333333</color>
|
<color name="backgroundDark">#333333</color>
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
<string name="popular">POPULAR</string>
|
<string name="popular">POPULAR</string>
|
||||||
<string name="bookmarks">BOOKMARKS</string>
|
<string name="bookmarks">BOOKMARKS</string>
|
||||||
<string name="goto_url_hint">Type a domain url</string>
|
<string name="goto_url_hint">Type a domain url</string>
|
||||||
<string name="username_or_email">Username or email\u00A0</string>
|
<string name="username_or_email">Username or email</string>
|
||||||
<string name="password">Password\u00A0</string>
|
<string name="password">Password</string>
|
||||||
<string name="login">Login</string>
|
<string name="login">Login</string>
|
||||||
<string name="logout">Logout</string>
|
<string name="logout">Logout</string>
|
||||||
<string name="forgot_password">Forgot password?\u00A0</string>
|
<string name="forgot_password">Forgot password?\u00A0</string>
|
||||||
|
|
|
@ -2906,7 +2906,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
|
||||||
// collect them in a vector to separately remove them with handleKillNode (since eachNode has a read lock and
|
// collect them in a vector to separately remove them with handleKillNode (since eachNode has a read lock and
|
||||||
// we cannot recursively take the write lock required by handleKillNode)
|
// we cannot recursively take the write lock required by handleKillNode)
|
||||||
std::vector<SharedNodePointer> nodesToKill;
|
std::vector<SharedNodePointer> nodesToKill;
|
||||||
nodeList->eachNode([this, direction, replicationNodesInSettings, replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
|
nodeList->eachNode([direction, replicationNodesInSettings, replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
|
||||||
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
||||||
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
||||||
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),
|
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),
|
||||||
|
|
|
@ -23,6 +23,7 @@ Item {
|
||||||
property bool failAfterSignUp: false
|
property bool failAfterSignUp: false
|
||||||
|
|
||||||
function login() {
|
function login() {
|
||||||
|
flavorText.visible = false
|
||||||
mainTextContainer.visible = false
|
mainTextContainer.visible = false
|
||||||
toggleLoading(true)
|
toggleLoading(true)
|
||||||
loginDialog.login(usernameField.text, passwordField.text)
|
loginDialog.login(usernameField.text, passwordField.text)
|
||||||
|
@ -43,7 +44,7 @@ Item {
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
var targetWidth = Math.max(titleWidth, form.contentWidth);
|
var targetWidth = Math.max(titleWidth, form.contentWidth);
|
||||||
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height +
|
var targetHeight = hifi.dimensions.contentSpacing.y + flavorText.height + mainTextContainer.height +
|
||||||
4 * hifi.dimensions.contentSpacing.y + form.height;
|
4 * hifi.dimensions.contentSpacing.y + form.height;
|
||||||
|
|
||||||
if (additionalInformation.visible) {
|
if (additionalInformation.visible) {
|
||||||
|
@ -106,14 +107,15 @@ Item {
|
||||||
ShortcutText {
|
ShortcutText {
|
||||||
id: mainTextContainer
|
id: mainTextContainer
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: flavorText.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
margins: 0
|
margins: 0
|
||||||
topMargin: hifi.dimensions.contentSpacing.y
|
topMargin: 1.5 * hifi.dimensions.contentSpacing.y
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: false
|
visible: false
|
||||||
text: qsTr("Username or password incorrect.")
|
text: qsTr("Username or password incorrect.")
|
||||||
|
height: flavorText.height - 20
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
color: hifi.colors.redAccent
|
color: hifi.colors.redAccent
|
||||||
lineHeight: 1
|
lineHeight: 1
|
||||||
|
@ -128,7 +130,7 @@ Item {
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: mainTextContainer.bottom
|
top: mainTextContainer.bottom
|
||||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
topMargin: 1.5 * hifi.dimensions.contentSpacing.y
|
||||||
}
|
}
|
||||||
spacing: 2 * hifi.dimensions.contentSpacing.y
|
spacing: 2 * hifi.dimensions.contentSpacing.y
|
||||||
|
|
||||||
|
@ -139,6 +141,7 @@ Item {
|
||||||
focus: true
|
focus: true
|
||||||
placeholderText: "Username or Email"
|
placeholderText: "Username or Email"
|
||||||
activeFocusOnPress: true
|
activeFocusOnPress: true
|
||||||
|
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||||
|
|
||||||
ShortcutText {
|
ShortcutText {
|
||||||
z: 10
|
z: 10
|
||||||
|
@ -172,7 +175,7 @@ Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
placeholderText: "Password"
|
placeholderText: "Password"
|
||||||
activeFocusOnPress: true
|
activeFocusOnPress: true
|
||||||
echoMode: TextInput.Password
|
echoMode: passwordFieldMouseArea.showPassword ? TextInput.Normal : TextInput.Password
|
||||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||||
|
|
||||||
ShortcutText {
|
ShortcutText {
|
||||||
|
@ -212,29 +215,28 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: showPasswordImage
|
id: showPasswordImage
|
||||||
y: (passwordField.height - (passwordField.height * 16 / 23)) / 2
|
width: passwordField.height * 16 / 23
|
||||||
width: passwordField.width - (passwordField.width - (((passwordField.height) * 31/23)))
|
|
||||||
height: passwordField.height * 16 / 23
|
height: passwordField.height * 16 / 23
|
||||||
anchors {
|
anchors {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 3
|
rightMargin: 8
|
||||||
|
top: parent.top
|
||||||
|
topMargin: passwordFieldMouseArea.showPassword ? 6 : 8
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: passwordFieldMouseArea.showPassword ? 5 : 8
|
||||||
|
}
|
||||||
|
source: passwordFieldMouseArea.showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg"
|
||||||
|
MouseArea {
|
||||||
|
id: passwordFieldMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
property bool showPassword: false
|
||||||
|
onClicked: {
|
||||||
|
showPassword = !showPassword;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
source: "../../images/eyeOpen.svg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: passwordFieldMouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
property bool showPassword: false
|
|
||||||
onClicked: {
|
|
||||||
showPassword = !showPassword;
|
|
||||||
passwordField.echoMode = showPassword ? TextInput.Normal : TextInput.Password;
|
|
||||||
showPasswordImage.source = showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg";
|
|
||||||
showPasswordImage.height = showPassword ? passwordField.height : passwordField.height * 16 / 23;
|
|
||||||
showPasswordImage.y = showPassword ? 0 : (passwordField.height - showPasswordImage.height) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onReturnPressed: linkAccountBody.login()
|
Keys.onReturnPressed: linkAccountBody.login()
|
||||||
|
@ -284,7 +286,7 @@ Item {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 200
|
width: 200
|
||||||
|
|
||||||
text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login")
|
text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Log in")
|
||||||
color: hifi.buttons.blue
|
color: hifi.buttons.blue
|
||||||
|
|
||||||
onClicked: linkAccountBody.login()
|
onClicked: linkAccountBody.login()
|
||||||
|
@ -336,6 +338,7 @@ Item {
|
||||||
|
|
||||||
if (failAfterSignUp) {
|
if (failAfterSignUp) {
|
||||||
mainTextContainer.text = "Account created successfully."
|
mainTextContainer.text = "Account created successfully."
|
||||||
|
flavorText.visible = true
|
||||||
mainTextContainer.visible = true
|
mainTextContainer.visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +377,7 @@ Item {
|
||||||
UserActivityLogger.logAction("encourageLoginDialog", data);
|
UserActivityLogger.logAction("encourageLoginDialog", data);
|
||||||
Settings.setValue("loginDialogPoppedUp", false);
|
Settings.setValue("loginDialogPoppedUp", false);
|
||||||
}
|
}
|
||||||
|
flavorText.visible = true
|
||||||
mainTextContainer.visible = true
|
mainTextContainer.visible = true
|
||||||
toggleLoading(false)
|
toggleLoading(false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,7 +314,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
wearableUpdated(getCurrentWearable().id, jointIndex, properties);
|
wearableUpdated(getCurrentWearable().id, wearablesCombobox.currentIndex, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
|
|
|
@ -131,7 +131,7 @@ Rectangle {
|
||||||
print("Marketplace item tester unsupported assetType " + assetType);
|
print("Marketplace item tester unsupported assetType " + assetType);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trash": function(){
|
"trash": function(resource, assetType){
|
||||||
if ("application" === assetType) {
|
if ("application" === assetType) {
|
||||||
Commerce.uninstallApp(resource);
|
Commerce.uninstallApp(resource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,7 +269,7 @@ class RenderEventHandler : public QObject {
|
||||||
public:
|
public:
|
||||||
RenderEventHandler() {
|
RenderEventHandler() {
|
||||||
// Transfer to a new thread
|
// Transfer to a new thread
|
||||||
moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
|
moveToNewNamedThread(this, "RenderThread", [](QThread* renderThread) {
|
||||||
hifi::qt::addBlockingForbiddenThread("Render", renderThread);
|
hifi::qt::addBlockingForbiddenThread("Render", renderThread);
|
||||||
qApp->_lastTimeRendered.start();
|
qApp->_lastTimeRendered.start();
|
||||||
}, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority);
|
}, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority);
|
||||||
|
@ -1755,7 +1755,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
// we can unlock the desktop repositioning code, since all the positions will be
|
// we can unlock the desktop repositioning code, since all the positions will be
|
||||||
// relative to the desktop size for this plugin
|
// relative to the desktop size for this plugin
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
offscreenUi->getDesktop()->setProperty("repositionLocked", false);
|
connect(offscreenUi.data(), &OffscreenUi::desktopReady, []() {
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
auto desktop = offscreenUi->getDesktop();
|
||||||
|
if (desktop) {
|
||||||
|
desktop->setProperty("repositionLocked", false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Make sure we don't time out during slow operations at startup
|
// Make sure we don't time out during slow operations at startup
|
||||||
updateHeartbeat();
|
updateHeartbeat();
|
||||||
|
@ -2309,7 +2315,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
QTimer* checkLoginTimer = new QTimer(this);
|
QTimer* checkLoginTimer = new QTimer(this);
|
||||||
checkLoginTimer->setInterval(CHECK_LOGIN_TIMER);
|
checkLoginTimer->setInterval(CHECK_LOGIN_TIMER);
|
||||||
checkLoginTimer->setSingleShot(true);
|
checkLoginTimer->setSingleShot(true);
|
||||||
connect(checkLoginTimer, &QTimer::timeout, this, [this]() {
|
connect(checkLoginTimer, &QTimer::timeout, this, []() {
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||||
if (!accountManager->isLoggedIn()) {
|
if (!accountManager->isLoggedIn()) {
|
||||||
|
@ -3430,7 +3436,12 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
||||||
int urlIndex = arguments().indexOf(HIFI_URL_COMMAND_LINE_KEY);
|
int urlIndex = arguments().indexOf(HIFI_URL_COMMAND_LINE_KEY);
|
||||||
QString addressLookupString;
|
QString addressLookupString;
|
||||||
if (urlIndex != -1) {
|
if (urlIndex != -1) {
|
||||||
addressLookupString = arguments().value(urlIndex + 1);
|
QUrl url(arguments().value(urlIndex + 1));
|
||||||
|
if (url.scheme() == URL_SCHEME_HIFIAPP) {
|
||||||
|
Setting::Handle<QVariant>("startUpApp").set(url.path());
|
||||||
|
} else {
|
||||||
|
addressLookupString = url.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location";
|
static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location";
|
||||||
|
@ -4668,8 +4679,14 @@ void Application::idle() {
|
||||||
|
|
||||||
checkChangeCursor();
|
checkChangeCursor();
|
||||||
|
|
||||||
Stats::getInstance()->updateStats();
|
auto stats = Stats::getInstance();
|
||||||
AnimStats::getInstance()->updateStats();
|
if (stats) {
|
||||||
|
stats->updateStats();
|
||||||
|
}
|
||||||
|
auto animStats = AnimStats::getInstance();
|
||||||
|
if (animStats) {
|
||||||
|
animStats->updateStats();
|
||||||
|
}
|
||||||
|
|
||||||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||||
|
@ -7678,6 +7695,9 @@ void Application::openUrl(const QUrl& url) const {
|
||||||
if (!url.isEmpty()) {
|
if (!url.isEmpty()) {
|
||||||
if (url.scheme() == URL_SCHEME_HIFI) {
|
if (url.scheme() == URL_SCHEME_HIFI) {
|
||||||
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
|
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
|
||||||
|
} else if (url.scheme() == URL_SCHEME_HIFIAPP) {
|
||||||
|
QmlCommerce commerce;
|
||||||
|
commerce.openSystemApp(url.path());
|
||||||
} else {
|
} else {
|
||||||
// address manager did not handle - ask QDesktopServices to handle
|
// address manager did not handle - ask QDesktopServices to handle
|
||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
|
|
|
@ -157,7 +157,10 @@ void Application::paintGL() {
|
||||||
renderArgs._context->enableStereo(false);
|
renderArgs._context->enableStereo(false);
|
||||||
|
|
||||||
{
|
{
|
||||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
auto stats = Stats::getInstance();
|
||||||
|
if (stats) {
|
||||||
|
stats->setRenderDetails(renderArgs._details);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||||
|
|
|
@ -48,6 +48,10 @@ AvatarActionHold::~AvatarActionHold() {
|
||||||
myAvatar->removeHoldAction(this);
|
myAvatar->removeHoldAction(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
|
if (ownerEntity) {
|
||||||
|
ownerEntity->setTransitingWithAvatar(false);
|
||||||
|
}
|
||||||
|
|
||||||
#if WANT_DEBUG
|
#if WANT_DEBUG
|
||||||
qDebug() << "AvatarActionHold::~AvatarActionHold" << (void*)this;
|
qDebug() << "AvatarActionHold::~AvatarActionHold" << (void*)this;
|
||||||
|
@ -131,6 +135,15 @@ bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::
|
||||||
glm::vec3 palmPosition;
|
glm::vec3 palmPosition;
|
||||||
glm::quat palmRotation;
|
glm::quat palmRotation;
|
||||||
|
|
||||||
|
bool isTransitingWithAvatar = holdingAvatar->getTransit()->isTransiting();
|
||||||
|
if (isTransitingWithAvatar != _isTransitingWithAvatar) {
|
||||||
|
_isTransitingWithAvatar = isTransitingWithAvatar;
|
||||||
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
|
if (ownerEntity) {
|
||||||
|
ownerEntity->setTransitingWithAvatar(_isTransitingWithAvatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (holdingAvatar->isMyAvatar()) {
|
if (holdingAvatar->isMyAvatar()) {
|
||||||
std::shared_ptr<MyAvatar> myAvatar = avatarManager->getMyAvatar();
|
std::shared_ptr<MyAvatar> myAvatar = avatarManager->getMyAvatar();
|
||||||
|
|
||||||
|
@ -404,11 +417,14 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
||||||
_kinematicSetVelocity = kinematicSetVelocity;
|
_kinematicSetVelocity = kinematicSetVelocity;
|
||||||
_ignoreIK = ignoreIK;
|
_ignoreIK = ignoreIK;
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
|
||||||
auto ownerEntity = _ownerEntity.lock();
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
if (ownerEntity) {
|
if (ownerEntity) {
|
||||||
ownerEntity->setDynamicDataDirty(true);
|
ownerEntity->setDynamicDataDirty(true);
|
||||||
ownerEntity->setDynamicDataNeedsTransmit(true);
|
ownerEntity->setDynamicDataNeedsTransmit(true);
|
||||||
|
ownerEntity->setTransitingWithAvatar(myAvatar->getTransit()->isTransiting());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ private:
|
||||||
bool _kinematicSetVelocity { false };
|
bool _kinematicSetVelocity { false };
|
||||||
bool _previousSet { false };
|
bool _previousSet { false };
|
||||||
bool _ignoreIK { false };
|
bool _ignoreIK { false };
|
||||||
|
bool _isTransitingWithAvatar { false };
|
||||||
|
|
||||||
glm::vec3 _previousPositionalTarget;
|
glm::vec3 _previousPositionalTarget;
|
||||||
glm::quat _previousRotationalTarget;
|
glm::quat _previousRotationalTarget;
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,15 @@ AvatarManager::AvatarManager(QObject* parent) :
|
||||||
removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
|
removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const float AVATAR_TRANSIT_TRIGGER_DISTANCE = 1.0f;
|
||||||
|
const int AVATAR_TRANSIT_FRAME_COUNT = 11; // Based on testing
|
||||||
|
const int AVATAR_TRANSIT_FRAMES_PER_METER = 1; // Based on testing
|
||||||
|
|
||||||
|
_transitConfig._totalFrames = AVATAR_TRANSIT_FRAME_COUNT;
|
||||||
|
_transitConfig._triggerDistance = AVATAR_TRANSIT_TRIGGER_DISTANCE;
|
||||||
|
_transitConfig._framesPerMeter = AVATAR_TRANSIT_FRAMES_PER_METER;
|
||||||
|
_transitConfig._isDistanceBased = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||||
|
@ -129,6 +138,10 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "AvatarManager::updateMyAvatar()");
|
PerformanceWarning warn(showWarnings, "AvatarManager::updateMyAvatar()");
|
||||||
|
|
||||||
|
AvatarTransit::Status status = _myAvatar->updateTransit(deltaTime, _myAvatar->getNextPosition(), _transitConfig);
|
||||||
|
bool sendFirstTransitPackage = (status == AvatarTransit::Status::START_TRANSIT);
|
||||||
|
bool blockTransitData = (status == AvatarTransit::Status::TRANSITING);
|
||||||
|
|
||||||
_myAvatar->update(deltaTime);
|
_myAvatar->update(deltaTime);
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
_myAvatar->updateRenderItem(transaction);
|
_myAvatar->updateRenderItem(transaction);
|
||||||
|
@ -137,9 +150,13 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
quint64 dt = now - _lastSendAvatarDataTime;
|
quint64 dt = now - _lastSendAvatarDataTime;
|
||||||
|
|
||||||
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) {
|
|
||||||
|
if (sendFirstTransitPackage || (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused && !blockTransitData)) {
|
||||||
// send head/hand data to the avatar mixer and voxel server
|
// send head/hand data to the avatar mixer and voxel server
|
||||||
PerformanceTimer perfTimer("send");
|
PerformanceTimer perfTimer("send");
|
||||||
|
if (sendFirstTransitPackage) {
|
||||||
|
_myAvatar->overrideNextPackagePositionData(_myAvatar->getTransit()->getEndPosition());
|
||||||
|
}
|
||||||
_myAvatar->sendAvatarDataPacket();
|
_myAvatar->sendAvatarDataPacket();
|
||||||
_lastSendAvatarDataTime = now;
|
_lastSendAvatarDataTime = now;
|
||||||
_myAvatarSendRate.increment();
|
_myAvatarSendRate.increment();
|
||||||
|
@ -258,6 +275,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
if (inView && avatar->hasNewJointData()) {
|
if (inView && avatar->hasNewJointData()) {
|
||||||
numAvatarsUpdated++;
|
numAvatarsUpdated++;
|
||||||
}
|
}
|
||||||
|
avatar->_transit.update(deltaTime, avatar->_globalPosition, _transitConfig);
|
||||||
avatar->simulate(deltaTime, inView);
|
avatar->simulate(deltaTime, inView);
|
||||||
avatar->updateRenderItem(renderTransaction);
|
avatar->updateRenderItem(renderTransaction);
|
||||||
avatar->updateSpaceProxy(workloadTransaction);
|
avatar->updateSpaceProxy(workloadTransaction);
|
||||||
|
@ -811,7 +829,7 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
|
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
|
||||||
QJsonArray palData;
|
QJsonArray palData;
|
||||||
|
|
||||||
auto avatarMap = getHashCopy();
|
auto avatarMap = getHashCopy();
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "MyAvatar.h"
|
#include "MyAvatar.h"
|
||||||
#include "OtherAvatar.h"
|
#include "OtherAvatar.h"
|
||||||
|
|
||||||
|
|
||||||
using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -232,6 +233,8 @@ private:
|
||||||
mutable std::mutex _spaceLock;
|
mutable std::mutex _spaceLock;
|
||||||
workload::SpacePointer _space;
|
workload::SpacePointer _space;
|
||||||
std::vector<int32_t> _spaceProxiesToDelete;
|
std::vector<int32_t> _spaceProxiesToDelete;
|
||||||
|
|
||||||
|
AvatarTransit::TransitConfig _transitConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarManager_h
|
#endif // hifi_AvatarManager_h
|
||||||
|
|
|
@ -638,9 +638,8 @@ void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool ca
|
||||||
|
|
||||||
void MyAvatar::simulate(float deltaTime) {
|
void MyAvatar::simulate(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("simulate");
|
PerformanceTimer perfTimer("simulate");
|
||||||
|
|
||||||
animateScaleChanges(deltaTime);
|
animateScaleChanges(deltaTime);
|
||||||
|
|
||||||
setFlyingEnabled(getFlyingEnabled());
|
setFlyingEnabled(getFlyingEnabled());
|
||||||
|
|
||||||
if (_cauterizationNeedsUpdate) {
|
if (_cauterizationNeedsUpdate) {
|
||||||
|
@ -928,6 +927,7 @@ void MyAvatar::updateSensorToWorldMatrix() {
|
||||||
updateJointFromController(controller::Action::RIGHT_HAND, _controllerRightHandMatrixCache);
|
updateJointFromController(controller::Action::RIGHT_HAND, _controllerRightHandMatrixCache);
|
||||||
|
|
||||||
if (hasSensorToWorldScaleChanged) {
|
if (hasSensorToWorldScaleChanged) {
|
||||||
|
setTransitScale(sensorToWorldScale);
|
||||||
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1115,6 +1115,8 @@ public:
|
||||||
virtual QVariantList getAttachmentsVariant() const override;
|
virtual QVariantList getAttachmentsVariant() const override;
|
||||||
virtual void setAttachmentsVariant(const QVariantList& variant) override;
|
virtual void setAttachmentsVariant(const QVariantList& variant) override;
|
||||||
|
|
||||||
|
glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -47,6 +47,54 @@ QmlCommerce::QmlCommerce() {
|
||||||
_appsPath = PathUtils::getAppDataPath() + "Apps/";
|
_appsPath = PathUtils::getAppDataPath() + "Apps/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void QmlCommerce::openSystemApp(const QString& appName) {
|
||||||
|
static QMap<QString, QString> systemApps {
|
||||||
|
{"GOTO", "hifi/tablet/TabletAddressDialog.qml"},
|
||||||
|
{"PEOPLE", "hifi/Pal.qml"},
|
||||||
|
{"WALLET", "hifi/commerce/wallet/Wallet.qml"},
|
||||||
|
{"MARKET", "/marketplace.html"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static QMap<QString, QString> systemInject{
|
||||||
|
{"MARKET", "/scripts/system/html/js/marketplacesInject.js"}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
auto tablet = dynamic_cast<TabletProxy*>(
|
||||||
|
DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||||
|
|
||||||
|
QMap<QString, QString>::const_iterator appPathIter = systemApps.find(appName);
|
||||||
|
if (appPathIter != systemApps.end()) {
|
||||||
|
if (appPathIter->contains(".qml", Qt::CaseInsensitive)) {
|
||||||
|
tablet->loadQMLSource(*appPathIter);
|
||||||
|
}
|
||||||
|
else if (appPathIter->contains(".html", Qt::CaseInsensitive)) {
|
||||||
|
QMap<QString, QString>::const_iterator injectIter = systemInject.find(appName);
|
||||||
|
if (appPathIter == systemInject.end()) {
|
||||||
|
tablet->gotoWebScreen(NetworkingConstants::METAVERSE_SERVER_URL().toString() + *appPathIter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QString inject = "file:///" + qApp->applicationDirPath() + *injectIter;
|
||||||
|
tablet->gotoWebScreen(NetworkingConstants::METAVERSE_SERVER_URL().toString() + *appPathIter, inject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qCDebug(commerce) << "Attempted to open unknown type of URL!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qCDebug(commerce) << "Attempted to open unknown APP!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void QmlCommerce::getWalletStatus() {
|
void QmlCommerce::getWalletStatus() {
|
||||||
auto wallet = DependencyManager::get<Wallet>();
|
auto wallet = DependencyManager::get<Wallet>();
|
||||||
wallet->getWalletStatus();
|
wallet->getWalletStatus();
|
||||||
|
@ -360,7 +408,7 @@ bool QmlCommerce::openApp(const QString& itemHref) {
|
||||||
// Read from the file to know what .html or .qml document to open
|
// Read from the file to know what .html or .qml document to open
|
||||||
QFile appFile(_appsPath + "/" + appHref.fileName());
|
QFile appFile(_appsPath + "/" + appHref.fileName());
|
||||||
if (!appFile.open(QIODevice::ReadOnly)) {
|
if (!appFile.open(QIODevice::ReadOnly)) {
|
||||||
qCDebug(commerce) << "Couldn't open local .app.json file.";
|
qCDebug(commerce) << "Couldn't open local .app.json file:" << appFile;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QJsonDocument appFileJsonDocument = QJsonDocument::fromJson(appFile.readAll());
|
QJsonDocument appFileJsonDocument = QJsonDocument::fromJson(appFile.readAll());
|
||||||
|
|
|
@ -24,6 +24,7 @@ class QmlCommerce : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QmlCommerce();
|
QmlCommerce();
|
||||||
|
void openSystemApp(const QString& appPath);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void walletStatusResult(uint walletStatus);
|
void walletStatusResult(uint walletStatus);
|
||||||
|
|
|
@ -176,7 +176,7 @@ int main(int argc, const char* argv[]) {
|
||||||
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
||||||
if (parser.isSet(urlOption)) {
|
if (parser.isSet(urlOption)) {
|
||||||
QUrl url = QUrl(parser.value(urlOption));
|
QUrl url = QUrl(parser.value(urlOption));
|
||||||
if (url.isValid() && url.scheme() == URL_SCHEME_HIFI) {
|
if (url.isValid() && (url.scheme() == URL_SCHEME_HIFI || url.scheme() == URL_SCHEME_HIFIAPP)) {
|
||||||
qDebug() << "Writing URL to local socket";
|
qDebug() << "Writing URL to local socket";
|
||||||
socket.write(url.toString().toUtf8());
|
socket.write(url.toString().toUtf8());
|
||||||
if (!socket.waitForBytesWritten(5000)) {
|
if (!socket.waitForBytesWritten(5000)) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ class StartEndRenderState {
|
||||||
public:
|
public:
|
||||||
StartEndRenderState() {}
|
StartEndRenderState() {}
|
||||||
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
|
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
|
||||||
|
virtual ~StartEndRenderState() {}
|
||||||
|
|
||||||
const OverlayID& getStartID() const { return _startID; }
|
const OverlayID& getStartID() const { return _startID; }
|
||||||
const OverlayID& getEndID() const { return _endID; }
|
const OverlayID& getEndID() const { return _endID; }
|
||||||
|
|
|
@ -62,7 +62,6 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(glm::vec3 position READ getPosition)
|
Q_PROPERTY(glm::vec3 position READ getPosition)
|
||||||
Q_PROPERTY(glm::quat orientation READ getOrientation)
|
Q_PROPERTY(glm::quat orientation READ getOrientation)
|
||||||
Q_PROPERTY(bool mounted READ isMounted NOTIFY mountedChanged)
|
|
||||||
Q_PROPERTY(bool showTablet READ getShouldShowTablet)
|
Q_PROPERTY(bool showTablet READ getShouldShowTablet)
|
||||||
Q_PROPERTY(bool tabletContextualMode READ getTabletContextualMode)
|
Q_PROPERTY(bool tabletContextualMode READ getTabletContextualMode)
|
||||||
Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID)
|
Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID)
|
||||||
|
@ -350,7 +349,7 @@ public:
|
||||||
static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine);
|
static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine);
|
||||||
static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine);
|
static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine);
|
||||||
|
|
||||||
bool isMounted() const;
|
bool isMounted() const override;
|
||||||
|
|
||||||
void toggleShouldShowTablet();
|
void toggleShouldShowTablet();
|
||||||
void setShouldShowTablet(bool value);
|
void setShouldShowTablet(bool value);
|
||||||
|
|
|
@ -75,7 +75,14 @@ void OverlayConductor::centerUI() {
|
||||||
|
|
||||||
void OverlayConductor::update(float dt) {
|
void OverlayConductor::update(float dt) {
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
bool currentVisible = !offscreenUi->getDesktop()->property("pinned").toBool();
|
if (!offscreenUi) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto desktop = offscreenUi->getDesktop();
|
||||||
|
if (!desktop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool currentVisible = !desktop->property("pinned").toBool();
|
||||||
|
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
// centerUI when hmd mode is first enabled and mounted
|
// centerUI when hmd mode is first enabled and mounted
|
||||||
|
|
|
@ -74,7 +74,7 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
const float FULL_CIRCLE = 360.0f;
|
const float FULL_CIRCLE = 360.0f;
|
||||||
const float SLICES = 180.0f; // The amount of segment to create the circle
|
const float SLICES = 180.0f; // The amount of segment to create the circle
|
||||||
const float SLICE_ANGLE = FULL_CIRCLE / SLICES;
|
const float SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES);
|
||||||
const float MAX_COLOR = 255.0f;
|
const float MAX_COLOR = 255.0f;
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -111,28 +111,38 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
vec4 innerEndColor = vec4(toGlm(_innerEndColor), _innerEndAlpha) * pulseModifier;
|
vec4 innerEndColor = vec4(toGlm(_innerEndColor), _innerEndAlpha) * pulseModifier;
|
||||||
vec4 outerEndColor = vec4(toGlm(_outerEndColor), _outerEndAlpha) * pulseModifier;
|
vec4 outerEndColor = vec4(toGlm(_outerEndColor), _outerEndAlpha) * pulseModifier;
|
||||||
|
|
||||||
|
const auto startAtRadians = glm::radians(_startAt);
|
||||||
|
const auto endAtRadians = glm::radians(_endAt);
|
||||||
|
|
||||||
|
const auto totalRange = _endAt - _startAt;
|
||||||
if (_innerRadius <= 0) {
|
if (_innerRadius <= 0) {
|
||||||
_solidPrimitive = gpu::TRIANGLE_FAN;
|
_solidPrimitive = gpu::TRIANGLE_FAN;
|
||||||
points << vec2();
|
points << vec2();
|
||||||
colors << innerStartColor;
|
colors << innerStartColor;
|
||||||
for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
|
for (float angleRadians = startAtRadians; angleRadians < endAtRadians; angleRadians += SLICE_ANGLE_RADIANS) {
|
||||||
float range = (angle - _startAt) / (_endAt - _startAt);
|
float range = (angleRadians - startAtRadians) / totalRange;
|
||||||
float angleRadians = glm::radians(angle);
|
|
||||||
points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
colors << glm::mix(outerStartColor, outerEndColor, range);
|
colors << glm::mix(outerStartColor, outerEndColor, range);
|
||||||
}
|
}
|
||||||
|
points << glm::vec2(cosf(endAtRadians) * _outerRadius, sinf(endAtRadians) * _outerRadius);
|
||||||
|
colors << outerEndColor;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_solidPrimitive = gpu::TRIANGLE_STRIP;
|
_solidPrimitive = gpu::TRIANGLE_STRIP;
|
||||||
for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
|
for (float angleRadians = startAtRadians; angleRadians < endAtRadians; angleRadians += SLICE_ANGLE_RADIANS) {
|
||||||
float range = (angle - _startAt) / (_endAt - _startAt);
|
float range = (angleRadians - startAtRadians) / totalRange;
|
||||||
|
|
||||||
float angleRadians = glm::radians(angle);
|
|
||||||
points << glm::vec2(cosf(angleRadians) * _innerRadius, sinf(angleRadians) * _innerRadius);
|
points << glm::vec2(cosf(angleRadians) * _innerRadius, sinf(angleRadians) * _innerRadius);
|
||||||
colors << glm::mix(innerStartColor, innerEndColor, range);
|
colors << glm::mix(innerStartColor, innerEndColor, range);
|
||||||
|
|
||||||
points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
colors << glm::mix(outerStartColor, outerEndColor, range);
|
colors << glm::mix(outerStartColor, outerEndColor, range);
|
||||||
}
|
}
|
||||||
|
points << glm::vec2(cosf(endAtRadians) * _innerRadius, sinf(endAtRadians) * _innerRadius);
|
||||||
|
colors << innerEndColor;
|
||||||
|
|
||||||
|
points << glm::vec2(cosf(endAtRadians) * _outerRadius, sinf(endAtRadians) * _outerRadius);
|
||||||
|
colors << outerEndColor;
|
||||||
}
|
}
|
||||||
geometryCache->updateVertices(_quadVerticesID, points, colors);
|
geometryCache->updateVertices(_quadVerticesID, points, colors);
|
||||||
}
|
}
|
||||||
|
@ -147,29 +157,28 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
if (geometryChanged) {
|
if (geometryChanged) {
|
||||||
QVector<glm::vec2> points;
|
QVector<glm::vec2> points;
|
||||||
|
|
||||||
float angle = _startAt;
|
const auto startAtRadians = glm::radians(_startAt);
|
||||||
float angleInRadians = glm::radians(angle);
|
const auto endAtRadians = glm::radians(_endAt);
|
||||||
glm::vec2 firstPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
|
|
||||||
|
float angleRadians = startAtRadians;
|
||||||
|
glm::vec2 firstPoint(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
points << firstPoint;
|
points << firstPoint;
|
||||||
|
|
||||||
while (angle < _endAt) {
|
while (angleRadians < endAtRadians) {
|
||||||
angle += SLICE_ANGLE;
|
angleRadians += SLICE_ANGLE_RADIANS;
|
||||||
angleInRadians = glm::radians(angle);
|
glm::vec2 thisPoint(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
glm::vec2 thisPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
|
|
||||||
points << thisPoint;
|
points << thisPoint;
|
||||||
|
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
angle += SLICE_ANGLE / 2.0f; // short gap
|
angleRadians += SLICE_ANGLE_RADIANS / 2.0f; // short gap
|
||||||
angleInRadians = glm::radians(angle);
|
glm::vec2 dashStartPoint(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
glm::vec2 dashStartPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
|
|
||||||
points << dashStartPoint;
|
points << dashStartPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the last slice portion....
|
// get the last slice portion....
|
||||||
angle = _endAt;
|
angleRadians = endAtRadians;
|
||||||
angleInRadians = glm::radians(angle);
|
glm::vec2 lastPoint(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
|
||||||
glm::vec2 lastPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
|
|
||||||
points << lastPoint;
|
points << lastPoint;
|
||||||
geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha()));
|
geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,6 @@ void Text3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||||
|
|
||||||
glm::vec2 clipMinimum(0.0f, 0.0f);
|
|
||||||
glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor,
|
glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor,
|
||||||
(dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor);
|
(dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor);
|
||||||
|
|
||||||
|
@ -296,4 +295,4 @@ QSizeF Text3DOverlay::textSize(const QString& text) const {
|
||||||
float pointToWorldScale = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
float pointToWorldScale = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||||
|
|
||||||
return QSizeF(extents.x, extents.y) * pointToWorldScale;
|
return QSizeF(extents.x, extents.y) * pointToWorldScale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define hifi_AudioHRTF_h
|
#define hifi_AudioHRTF_h
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static const int HRTF_AZIMUTHS = 72; // 360 / 5-degree steps
|
static const int HRTF_AZIMUTHS = 72; // 360 / 5-degree steps
|
||||||
static const int HRTF_TAPS = 64; // minimum-phase FIR coefficients
|
static const int HRTF_TAPS = 64; // minimum-phase FIR coefficients
|
||||||
|
@ -56,6 +57,27 @@ public:
|
||||||
void setGainAdjustment(float gain) { _gainAdjust = HRTF_GAIN * gain; };
|
void setGainAdjustment(float gain) { _gainAdjust = HRTF_GAIN * gain; };
|
||||||
float getGainAdjustment() { return _gainAdjust; }
|
float getGainAdjustment() { return _gainAdjust; }
|
||||||
|
|
||||||
|
// clear internal state, but retain settings
|
||||||
|
void reset() {
|
||||||
|
// FIR history
|
||||||
|
memset(_firState, 0, sizeof(_firState));
|
||||||
|
|
||||||
|
// integer delay history
|
||||||
|
memset(_delayState, 0, sizeof(_delayState));
|
||||||
|
|
||||||
|
// biquad history
|
||||||
|
memset(_bqState, 0, sizeof(_bqState));
|
||||||
|
|
||||||
|
// parameter history
|
||||||
|
_azimuthState = 0.0f;
|
||||||
|
_distanceState = 0.0f;
|
||||||
|
_gainState = 0.0f;
|
||||||
|
|
||||||
|
// _gainAdjust is retained
|
||||||
|
|
||||||
|
_silentState = true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioHRTF(const AudioHRTF&) = delete;
|
AudioHRTF(const AudioHRTF&) = delete;
|
||||||
AudioHRTF& operator=(const AudioHRTF&) = delete;
|
AudioHRTF& operator=(const AudioHRTF&) = delete;
|
||||||
|
@ -88,7 +110,7 @@ private:
|
||||||
// global and local gain adjustment
|
// global and local gain adjustment
|
||||||
float _gainAdjust = HRTF_GAIN;
|
float _gainAdjust = HRTF_GAIN;
|
||||||
|
|
||||||
bool _silentState = false;
|
bool _silentState = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AudioHRTF_h
|
#endif // AudioHRTF_h
|
||||||
|
|
|
@ -113,6 +113,80 @@ void Avatar::setShowNamesAboveHeads(bool show) {
|
||||||
showNamesAboveHeads = show;
|
showNamesAboveHeads = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
glm::vec3 currentPosition = _isTransiting ? _currentPosition : avatarPosition;
|
||||||
|
float oneFrameDistance = glm::length(currentPosition - _lastPosition);
|
||||||
|
const float MAX_TRANSIT_DISTANCE = 30.0f;
|
||||||
|
float scaledMaxTransitDistance = MAX_TRANSIT_DISTANCE * _scale;
|
||||||
|
if (oneFrameDistance > config._triggerDistance && oneFrameDistance < scaledMaxTransitDistance && !_isTransiting) {
|
||||||
|
start(deltaTime, _lastPosition, currentPosition, config);
|
||||||
|
}
|
||||||
|
_lastPosition = currentPosition;
|
||||||
|
_status = updatePosition(deltaTime);
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarTransit::start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
_startPosition = startPosition;
|
||||||
|
_endPosition = endPosition;
|
||||||
|
|
||||||
|
_transitLine = endPosition - startPosition;
|
||||||
|
_totalDistance = glm::length(_transitLine);
|
||||||
|
_easeType = config._easeType;
|
||||||
|
const float REFERENCE_FRAMES_PER_SECOND = 30.0f;
|
||||||
|
|
||||||
|
int transitFrames = (!config._isDistanceBased) ? config._totalFrames : config._framesPerMeter * _totalDistance;
|
||||||
|
_totalTime = (float)transitFrames / REFERENCE_FRAMES_PER_SECOND;
|
||||||
|
_currentTime = 0.0f;
|
||||||
|
_isTransiting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AvatarTransit::getEaseValue(AvatarTransit::EaseType type, float value) {
|
||||||
|
switch (type) {
|
||||||
|
case EaseType::NONE:
|
||||||
|
return value;
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_IN:
|
||||||
|
return value * value;
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_OUT:
|
||||||
|
return value * (2.0f - value);
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_IN_OUT:
|
||||||
|
return (value < 0.5f) ? 2.0f * value * value : -1.0f + (4.0f - 2.0f * value) * value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status AvatarTransit::updatePosition(float deltaTime) {
|
||||||
|
Status status = Status::IDLE;
|
||||||
|
if (_isTransiting) {
|
||||||
|
float nextTime = _currentTime + deltaTime;
|
||||||
|
glm::vec3 newPosition;
|
||||||
|
if (nextTime >= _totalTime) {
|
||||||
|
_currentPosition = _endPosition;
|
||||||
|
_isTransiting = false;
|
||||||
|
status = Status::END_TRANSIT;
|
||||||
|
} else {
|
||||||
|
if (_currentTime == 0) {
|
||||||
|
status = Status::START_TRANSIT;
|
||||||
|
} else {
|
||||||
|
status = Status::TRANSITING;
|
||||||
|
}
|
||||||
|
float percentageIntoTransit = nextTime / _totalTime;
|
||||||
|
_currentPosition = _startPosition + getEaseValue(_easeType, percentageIntoTransit) * _transitLine;
|
||||||
|
}
|
||||||
|
_currentTime = nextTime;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvatarTransit::getNextPosition(glm::vec3& nextPosition) {
|
||||||
|
nextPosition = _currentPosition;
|
||||||
|
return _isTransiting;
|
||||||
|
}
|
||||||
|
|
||||||
Avatar::Avatar(QThread* thread) :
|
Avatar::Avatar(QThread* thread) :
|
||||||
_voiceSphereID(GeometryCache::UNKNOWN_ID)
|
_voiceSphereID(GeometryCache::UNKNOWN_ID)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +523,18 @@ void Avatar::relayJointDataToChildren() {
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime, bool inView) {
|
void Avatar::simulate(float deltaTime, bool inView) {
|
||||||
PROFILE_RANGE(simulation, "simulate");
|
PROFILE_RANGE(simulation, "simulate");
|
||||||
|
|
||||||
|
if (_transit.isTransiting()) {
|
||||||
|
glm::vec3 nextPosition;
|
||||||
|
if (_transit.getNextPosition(nextPosition)) {
|
||||||
|
_globalPosition = nextPosition;
|
||||||
|
_globalPositionChanged = usecTimestampNow();
|
||||||
|
if (!hasParent()) {
|
||||||
|
setLocalPosition(nextPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_simulationRate.increment();
|
_simulationRate.increment();
|
||||||
if (inView) {
|
if (inView) {
|
||||||
_simulationInViewRate.increment();
|
_simulationInViewRate.increment();
|
||||||
|
@ -460,7 +545,7 @@ void Avatar::simulate(float deltaTime, bool inView) {
|
||||||
PROFILE_RANGE(simulation, "updateJoints");
|
PROFILE_RANGE(simulation, "updateJoints");
|
||||||
if (inView) {
|
if (inView) {
|
||||||
Head* head = getHead();
|
Head* head = getHead();
|
||||||
if (_hasNewJointData) {
|
if (_hasNewJointData || _transit.isTransiting()) {
|
||||||
_skeletonModel->getRig().copyJointsFromJointData(_jointData);
|
_skeletonModel->getRig().copyJointsFromJointData(_jointData);
|
||||||
glm::mat4 rootTransform = glm::scale(_skeletonModel->getScale()) * glm::translate(_skeletonModel->getOffset());
|
glm::mat4 rootTransform = glm::scale(_skeletonModel->getScale()) * glm::translate(_skeletonModel->getOffset());
|
||||||
_skeletonModel->getRig().computeExternalPoses(rootTransform);
|
_skeletonModel->getRig().computeExternalPoses(rootTransform);
|
||||||
|
@ -1881,6 +1966,22 @@ float Avatar::getUnscaledEyeHeightFromSkeleton() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status Avatar::updateTransit(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
return _transit.update(deltaTime, avatarPosition, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::setTransitScale(float scale) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
return _transit.setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::overrideNextPackagePositionData(const glm::vec3& position) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
_overrideGlobalPosition = true;
|
||||||
|
_globalPositionOverride = position;
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
void Avatar::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||||
_materials[parentMaterialName].push(material);
|
_materials[parentMaterialName].push(material);
|
||||||
|
|
|
@ -50,6 +50,62 @@ enum ScreenTintLayer {
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
|
class AvatarTransit {
|
||||||
|
public:
|
||||||
|
enum Status {
|
||||||
|
IDLE = 0,
|
||||||
|
START_TRANSIT,
|
||||||
|
TRANSITING,
|
||||||
|
END_TRANSIT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EaseType {
|
||||||
|
NONE = 0,
|
||||||
|
EASE_IN,
|
||||||
|
EASE_OUT,
|
||||||
|
EASE_IN_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransitConfig {
|
||||||
|
TransitConfig() {};
|
||||||
|
int _totalFrames { 0 };
|
||||||
|
int _framesPerMeter { 0 };
|
||||||
|
bool _isDistanceBased { false };
|
||||||
|
float _triggerDistance { 0 };
|
||||||
|
EaseType _easeType { EaseType::EASE_OUT };
|
||||||
|
};
|
||||||
|
|
||||||
|
AvatarTransit() {};
|
||||||
|
Status update(float deltaTime, const glm::vec3& avatarPosition, const TransitConfig& config);
|
||||||
|
Status getStatus() { return _status; }
|
||||||
|
bool isTransiting() { return _isTransiting; }
|
||||||
|
glm::vec3 getCurrentPosition() { return _currentPosition; }
|
||||||
|
bool getNextPosition(glm::vec3& nextPosition);
|
||||||
|
glm::vec3 getEndPosition() { return _endPosition; }
|
||||||
|
float getTransitTime() { return _totalTime; }
|
||||||
|
void setScale(float scale) { _scale = scale; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Status updatePosition(float deltaTime);
|
||||||
|
void start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const TransitConfig& config);
|
||||||
|
float getEaseValue(AvatarTransit::EaseType type, float value);
|
||||||
|
bool _isTransiting { false };
|
||||||
|
|
||||||
|
glm::vec3 _startPosition;
|
||||||
|
glm::vec3 _endPosition;
|
||||||
|
glm::vec3 _currentPosition;
|
||||||
|
|
||||||
|
glm::vec3 _lastPosition;
|
||||||
|
|
||||||
|
glm::vec3 _transitLine;
|
||||||
|
float _totalDistance { 0.0f };
|
||||||
|
float _totalTime { 0.0f };
|
||||||
|
float _currentTime { 0.0f };
|
||||||
|
EaseType _easeType { EaseType::EASE_OUT };
|
||||||
|
Status _status { Status::IDLE };
|
||||||
|
float _scale { 1.0f };
|
||||||
|
};
|
||||||
|
|
||||||
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -370,6 +426,13 @@ public:
|
||||||
|
|
||||||
virtual scriptable::ScriptableModelBase getScriptableModel() override;
|
virtual scriptable::ScriptableModelBase getScriptableModel() override;
|
||||||
|
|
||||||
|
std::shared_ptr<AvatarTransit> getTransit() { return std::make_shared<AvatarTransit>(_transit); };
|
||||||
|
|
||||||
|
AvatarTransit::Status updateTransit(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config);
|
||||||
|
void setTransitScale(float scale);
|
||||||
|
|
||||||
|
void overrideNextPackagePositionData(const glm::vec3& position);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetScaleChanged(float targetScale);
|
void targetScaleChanged(float targetScale);
|
||||||
|
|
||||||
|
@ -505,6 +568,7 @@ protected:
|
||||||
RateCounter<> _skeletonModelSimulationRate;
|
RateCounter<> _skeletonModelSimulationRate;
|
||||||
RateCounter<> _jointDataSimulationRate;
|
RateCounter<> _jointDataSimulationRate;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class AvatarEntityDataHash {
|
class AvatarEntityDataHash {
|
||||||
public:
|
public:
|
||||||
|
@ -528,6 +592,9 @@ protected:
|
||||||
bool _reconstructSoftEntitiesJointMap { false };
|
bool _reconstructSoftEntitiesJointMap { false };
|
||||||
float _modelScale { 1.0f };
|
float _modelScale { 1.0f };
|
||||||
|
|
||||||
|
AvatarTransit _transit;
|
||||||
|
std::mutex _transitLock;
|
||||||
|
|
||||||
static int _jointConesID;
|
static int _jointConesID;
|
||||||
|
|
||||||
int _voiceSphereID;
|
int _voiceSphereID;
|
||||||
|
|
|
@ -369,7 +369,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
|
|
||||||
if (hasAvatarGlobalPosition) {
|
if (hasAvatarGlobalPosition) {
|
||||||
auto startSection = destinationBuffer;
|
auto startSection = destinationBuffer;
|
||||||
AVATAR_MEMCPY(_globalPosition);
|
if (_overrideGlobalPosition) {
|
||||||
|
AVATAR_MEMCPY(_globalPositionOverride);
|
||||||
|
} else {
|
||||||
|
AVATAR_MEMCPY(_globalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int numBytes = destinationBuffer - startSection;
|
int numBytes = destinationBuffer - startSection;
|
||||||
|
|
||||||
|
@ -2088,6 +2093,10 @@ void AvatarData::sendAvatarDataPacket(bool sendAll) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_overrideGlobalPosition) {
|
||||||
|
_overrideGlobalPosition = false;
|
||||||
|
}
|
||||||
|
|
||||||
doneEncoding(cullSmallData);
|
doneEncoding(cullSmallData);
|
||||||
|
|
||||||
static AvatarDataSequenceNumber sequenceNumber = 0;
|
static AvatarDataSequenceNumber sequenceNumber = 0;
|
||||||
|
|
|
@ -1372,7 +1372,8 @@ protected:
|
||||||
// where Entities are located. This is currently only used by the mixer to decide how often to send
|
// where Entities are located. This is currently only used by the mixer to decide how often to send
|
||||||
// updates about one avatar to another.
|
// updates about one avatar to another.
|
||||||
glm::vec3 _globalPosition { 0, 0, 0 };
|
glm::vec3 _globalPosition { 0, 0, 0 };
|
||||||
|
glm::vec3 _globalPositionOverride { 0, 0, 0 };
|
||||||
|
bool _overrideGlobalPosition { false };
|
||||||
|
|
||||||
quint64 _globalPositionChanged { 0 };
|
quint64 _globalPositionChanged { 0 };
|
||||||
quint64 _avatarBoundingBoxChanged { 0 };
|
quint64 _avatarBoundingBoxChanged { 0 };
|
||||||
|
|
|
@ -266,6 +266,7 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// have the matching (or new) avatar parse the data from the packet
|
// have the matching (or new) avatar parse the data from the packet
|
||||||
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
||||||
message->seek(positionBeforeRead + bytesRead);
|
message->seek(positionBeforeRead + bytesRead);
|
||||||
|
@ -316,7 +317,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
// In this case, the "sendingNode" is the Avatar Mixer.
|
// In this case, the "sendingNode" is the Avatar Mixer.
|
||||||
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
||||||
_replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged);
|
_replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +329,7 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> mess
|
||||||
// grab the avatar so we can ask it to process trait data
|
// grab the avatar so we can ask it to process trait data
|
||||||
bool isNewAvatar;
|
bool isNewAvatar;
|
||||||
auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar);
|
auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar);
|
||||||
|
|
||||||
// read the first trait type for this avatar
|
// read the first trait type for this avatar
|
||||||
AvatarTraits::TraitType traitType;
|
AvatarTraits::TraitType traitType;
|
||||||
message->readPrimitive(&traitType);
|
message->readPrimitive(&traitType);
|
||||||
|
|
|
@ -98,6 +98,7 @@ enum Hand {
|
||||||
class InputDevice {
|
class InputDevice {
|
||||||
public:
|
public:
|
||||||
InputDevice(const QString& name) : _name(name) {}
|
InputDevice(const QString& name) : _name(name) {}
|
||||||
|
virtual ~InputDevice() {}
|
||||||
|
|
||||||
using Pointer = std::shared_ptr<InputDevice>;
|
using Pointer = std::shared_ptr<InputDevice>;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
|
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
|
||||||
: _children({ first, second }) {}
|
: _children({ first, second }) {}
|
||||||
|
|
||||||
|
virtual ~AndConditional() {}
|
||||||
|
|
||||||
virtual bool satisfied() override;
|
virtual bool satisfied() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace controller {
|
||||||
class EndpointConditional : public Conditional {
|
class EndpointConditional : public Conditional {
|
||||||
public:
|
public:
|
||||||
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
||||||
|
virtual ~EndpointConditional() {}
|
||||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
||||||
private:
|
private:
|
||||||
Endpoint::Pointer _endpoint;
|
Endpoint::Pointer _endpoint;
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace controller {
|
||||||
using Pointer = std::shared_ptr<NotConditional>;
|
using Pointer = std::shared_ptr<NotConditional>;
|
||||||
|
|
||||||
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
|
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
|
||||||
|
virtual ~NotConditional() {}
|
||||||
|
|
||||||
virtual bool satisfied() override;
|
virtual bool satisfied() override;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ class ClampFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ClampFilter);
|
REGISTER_FILTER_CLASS(ClampFilter);
|
||||||
public:
|
public:
|
||||||
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
||||||
|
virtual ~ClampFilter() {}
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return glm::clamp(value, _min, _max);
|
return glm::clamp(value, _min, _max);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class ConstrainToIntegerFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
|
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
|
||||||
public:
|
public:
|
||||||
ConstrainToIntegerFilter() {};
|
ConstrainToIntegerFilter() {};
|
||||||
|
virtual ~ConstrainToIntegerFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return glm::sign(value);
|
return glm::sign(value);
|
||||||
|
|
|
@ -18,6 +18,7 @@ class ConstrainToPositiveIntegerFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
|
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
|
||||||
public:
|
public:
|
||||||
ConstrainToPositiveIntegerFilter() {};
|
ConstrainToPositiveIntegerFilter() {};
|
||||||
|
virtual ~ConstrainToPositiveIntegerFilter() {};
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return (value <= 0.0f) ? 0.0f : 1.0f;
|
return (value <= 0.0f) ? 0.0f : 1.0f;
|
||||||
|
|
|
@ -18,6 +18,7 @@ class DeadZoneFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(DeadZoneFilter);
|
REGISTER_FILTER_CLASS(DeadZoneFilter);
|
||||||
public:
|
public:
|
||||||
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
||||||
|
virtual ~DeadZoneFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace controller {
|
||||||
ExponentialSmoothingFilter() {}
|
ExponentialSmoothingFilter() {}
|
||||||
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
||||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||||
|
virtual ~ExponentialSmoothingFilter() {}
|
||||||
|
|
||||||
float apply(float value) const override { return value; }
|
float apply(float value) const override { return value; }
|
||||||
Pose apply(Pose value) const override;
|
Pose apply(Pose value) const override;
|
||||||
|
|
|
@ -18,6 +18,7 @@ class HysteresisFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(HysteresisFilter);
|
REGISTER_FILTER_CLASS(HysteresisFilter);
|
||||||
public:
|
public:
|
||||||
HysteresisFilter(float min = 0.25, float max = 0.75);
|
HysteresisFilter(float min = 0.25, float max = 0.75);
|
||||||
|
virtual ~HysteresisFilter() {}
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
|
@ -19,6 +19,7 @@ class InvertFilter : public ScaleFilter {
|
||||||
public:
|
public:
|
||||||
using ScaleFilter::parseParameters;
|
using ScaleFilter::parseParameters;
|
||||||
InvertFilter() : ScaleFilter(-1.0f) {}
|
InvertFilter() : ScaleFilter(-1.0f) {}
|
||||||
|
virtual ~InvertFilter() {}
|
||||||
|
|
||||||
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
|
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace controller {
|
||||||
LowVelocityFilter() {}
|
LowVelocityFilter() {}
|
||||||
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
||||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||||
|
virtual ~LowVelocityFilter() {}
|
||||||
|
|
||||||
float apply(float value) const override { return value; }
|
float apply(float value) const override { return value; }
|
||||||
Pose apply(Pose newPose) const override;
|
Pose apply(Pose newPose) const override;
|
||||||
|
|
|
@ -10,6 +10,7 @@ class NotFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(NotFilter);
|
REGISTER_FILTER_CLASS(NotFilter);
|
||||||
public:
|
public:
|
||||||
NotFilter();
|
NotFilter();
|
||||||
|
virtual ~NotFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
|
@ -21,6 +21,7 @@ class PostTransformFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
PostTransformFilter() { }
|
PostTransformFilter() { }
|
||||||
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||||
|
virtual ~PostTransformFilter() {}
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
||||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
||||||
|
|
|
@ -20,6 +20,7 @@ class PulseFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
PulseFilter() {}
|
PulseFilter() {}
|
||||||
PulseFilter(float interval) : _interval(interval) {}
|
PulseFilter(float interval) : _interval(interval) {}
|
||||||
|
virtual ~PulseFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ class RotateFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
RotateFilter() { }
|
RotateFilter() { }
|
||||||
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
||||||
|
virtual ~RotateFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ class ScaleFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
ScaleFilter() {}
|
ScaleFilter() {}
|
||||||
ScaleFilter(float scale) : _scale(scale) {}
|
ScaleFilter(float scale) : _scale(scale) {}
|
||||||
|
virtual ~ScaleFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return value * _scale;
|
return value * _scale;
|
||||||
|
|
|
@ -21,6 +21,7 @@ class TransformFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
TransformFilter() { }
|
TransformFilter() { }
|
||||||
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||||
|
virtual ~TransformFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
||||||
|
|
|
@ -21,6 +21,7 @@ class TranslateFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
TranslateFilter() { }
|
TranslateFilter() { }
|
||||||
TranslateFilter(glm::vec3 translate) : _translate(translate) {}
|
TranslateFilter(glm::vec3 translate) : _translate(translate) {}
|
||||||
|
virtual ~TranslateFilter() {}
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.transform(glm::translate(_translate)); }
|
virtual Pose apply(Pose value) const override { return value.transform(glm::translate(_translate)); }
|
||||||
|
|
|
@ -20,6 +20,7 @@ class AbstractHMDScriptingInterface : public QObject {
|
||||||
Q_PROPERTY(float eyeHeight READ getEyeHeight)
|
Q_PROPERTY(float eyeHeight READ getEyeHeight)
|
||||||
Q_PROPERTY(float playerHeight READ getPlayerHeight)
|
Q_PROPERTY(float playerHeight READ getPlayerHeight)
|
||||||
Q_PROPERTY(float ipdScale READ getIPDScale WRITE setIPDScale NOTIFY IPDScaleChanged)
|
Q_PROPERTY(float ipdScale READ getIPDScale WRITE setIPDScale NOTIFY IPDScaleChanged)
|
||||||
|
Q_PROPERTY(bool mounted READ isMounted NOTIFY mountedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractHMDScriptingInterface();
|
AbstractHMDScriptingInterface();
|
||||||
|
@ -29,6 +30,7 @@ public:
|
||||||
float getIPDScale() const;
|
float getIPDScale() const;
|
||||||
void setIPDScale(float ipdScale);
|
void setIPDScale(float ipdScale);
|
||||||
bool isHMDMode() const;
|
bool isHMDMode() const;
|
||||||
|
virtual bool isMounted() const = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -187,6 +187,13 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
|
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
|
||||||
|
EntityItemPointer entity = getTree()->findEntityByID(entityID);
|
||||||
|
if (entity) {
|
||||||
|
entity->setScriptHasFinishedPreload(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::clear() {
|
void EntityTreeRenderer::clear() {
|
||||||
|
@ -512,7 +519,11 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
|
||||||
// be ignored because they can have events fired on them.
|
// be ignored because they can have events fired on them.
|
||||||
// FIXME - this could be optimized further by determining if the script is loaded
|
// FIXME - this could be optimized further by determining if the script is loaded
|
||||||
// and if it has either an enterEntity or leaveEntity method
|
// and if it has either an enterEntity or leaveEntity method
|
||||||
if (isZone || hasScript) {
|
//
|
||||||
|
// also, don't flag a scripted entity as containing the avatar until the script is loaded,
|
||||||
|
// so that the script is awake in time to receive the "entityEntity" call (even if the entity is a zone).
|
||||||
|
if ((!hasScript && isZone) ||
|
||||||
|
(hasScript && entity->isScriptPreloadFinished())) {
|
||||||
// now check to see if the point contains our entity, this can be expensive if
|
// now check to see if the point contains our entity, this can be expensive if
|
||||||
// the entity has a collision hull
|
// the entity has a collision hull
|
||||||
if (entity->contains(_avatarPosition)) {
|
if (entity->contains(_avatarPosition)) {
|
||||||
|
@ -972,6 +983,7 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
|
||||||
entity->scriptHasUnloaded();
|
entity->scriptHasUnloaded();
|
||||||
}
|
}
|
||||||
if (shouldLoad) {
|
if (shouldLoad) {
|
||||||
|
entity->setScriptHasFinishedPreload(false);
|
||||||
_entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload);
|
_entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload);
|
||||||
entity->scriptHasPreloaded();
|
entity->scriptHasPreloaded();
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,8 +250,8 @@ void RenderableModelEntityItem::updateModelBounds() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties RenderableModelEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = ModelEntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = ModelEntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
if (_originalTexturesRead) {
|
if (_originalTexturesRead) {
|
||||||
properties.setTextureNames(_originalTextures);
|
properties.setTextureNames(_originalTextures);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
void doInitialModelSimulation();
|
void doInitialModelSimulation();
|
||||||
void updateModelBounds();
|
void updateModelBounds();
|
||||||
|
|
||||||
|
|
|
@ -97,10 +97,10 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
auto entity = getEntity();
|
auto entity = getEntity();
|
||||||
_position = entity->getWorldPosition();
|
_position = entity->getWorldPosition();
|
||||||
_dimensions = entity->getScaledDimensions();
|
_dimensions = entity->getUnscaledDimensions(); // get unscaled to avoid scaling twice
|
||||||
_orientation = entity->getWorldOrientation();
|
_orientation = entity->getWorldOrientation();
|
||||||
updateModelTransformAndBound();
|
updateModelTransformAndBound();
|
||||||
_renderTransform = getModelTransform();
|
_renderTransform = getModelTransform(); // contains parent scale, if this entity scales with its parent
|
||||||
if (_shape == entity::Sphere) {
|
if (_shape == entity::Sphere) {
|
||||||
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1251,9 +1251,10 @@ quint64 EntityItem::getExpiry() const {
|
||||||
return getCreated() + (quint64)(getLifetime() * (float)USECS_PER_SECOND);
|
return getCreated() + (quint64)(getLifetime() * (float)USECS_PER_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EncodeBitstreamParams params; // unknown
|
EncodeBitstreamParams params; // unknown
|
||||||
EntityPropertyFlags propertyFlags = desiredProperties.isEmpty() ? getEntityProperties(params) : desiredProperties;
|
const EntityPropertyFlags propertyFlags = !allowEmptyDesiredProperties && desiredProperties.isEmpty() ?
|
||||||
|
getEntityProperties(params) : desiredProperties;
|
||||||
EntityItemProperties properties(propertyFlags);
|
EntityItemProperties properties(propertyFlags);
|
||||||
properties._id = getID();
|
properties._id = getID();
|
||||||
properties._idSet = true;
|
properties._idSet = true;
|
||||||
|
@ -3197,3 +3198,26 @@ void EntityItem::setCloneIDs(const QVector<QUuid>& cloneIDs) {
|
||||||
_cloneIDs = cloneIDs;
|
_cloneIDs = cloneIDs;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItem::shouldPreloadScript() const {
|
||||||
|
return !_script.isEmpty() && ((_loadedScript != _script) || (_loadedScriptTimestamp != _scriptTimestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::scriptHasPreloaded() {
|
||||||
|
_loadedScript = _script;
|
||||||
|
_loadedScriptTimestamp = _scriptTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::scriptHasUnloaded() {
|
||||||
|
_loadedScript = "";
|
||||||
|
_loadedScriptTimestamp = 0;
|
||||||
|
_scriptPreloadFinished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::setScriptHasFinishedPreload(bool value) {
|
||||||
|
_scriptPreloadFinished = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItem::isScriptPreloadFinished() {
|
||||||
|
return _scriptPreloadFinished;
|
||||||
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
EntityItemID getEntityItemID() const { return EntityItemID(_id); }
|
EntityItemID getEntityItemID() const { return EntityItemID(_id); }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties = EntityPropertyFlags(), bool allowEmptyDesiredProperties = false) const;
|
||||||
|
|
||||||
/// returns true if something changed
|
/// returns true if something changed
|
||||||
// This function calls setSubClass properties and detects if any property changes value.
|
// This function calls setSubClass properties and detects if any property changes value.
|
||||||
|
@ -441,6 +441,8 @@ public:
|
||||||
|
|
||||||
void setDynamicDataNeedsTransmit(bool value) const { _dynamicDataNeedsTransmit = value; }
|
void setDynamicDataNeedsTransmit(bool value) const { _dynamicDataNeedsTransmit = value; }
|
||||||
bool dynamicDataNeedsTransmit() const { return _dynamicDataNeedsTransmit; }
|
bool dynamicDataNeedsTransmit() const { return _dynamicDataNeedsTransmit; }
|
||||||
|
void setTransitingWithAvatar(bool value) { _transitingWithAvatar = value; }
|
||||||
|
bool getTransitingWithAvatar() { return _transitingWithAvatar; }
|
||||||
|
|
||||||
bool shouldSuppressLocationEdits() const;
|
bool shouldSuppressLocationEdits() const;
|
||||||
|
|
||||||
|
@ -470,10 +472,11 @@ public:
|
||||||
/// We only want to preload if:
|
/// We only want to preload if:
|
||||||
/// there is some script, and either the script value or the scriptTimestamp
|
/// there is some script, and either the script value or the scriptTimestamp
|
||||||
/// value have changed since our last preload
|
/// value have changed since our last preload
|
||||||
bool shouldPreloadScript() const { return !_script.isEmpty() &&
|
bool shouldPreloadScript() const;
|
||||||
((_loadedScript != _script) || (_loadedScriptTimestamp != _scriptTimestamp)); }
|
void scriptHasPreloaded();
|
||||||
void scriptHasPreloaded() { _loadedScript = _script; _loadedScriptTimestamp = _scriptTimestamp; }
|
void scriptHasUnloaded();
|
||||||
void scriptHasUnloaded() { _loadedScript = ""; _loadedScriptTimestamp = 0; }
|
void setScriptHasFinishedPreload(bool value);
|
||||||
|
bool isScriptPreloadFinished();
|
||||||
|
|
||||||
bool getClientOnly() const { return _clientOnly; }
|
bool getClientOnly() const { return _clientOnly; }
|
||||||
virtual void setClientOnly(bool clientOnly) { _clientOnly = clientOnly; }
|
virtual void setClientOnly(bool clientOnly) { _clientOnly = clientOnly; }
|
||||||
|
@ -584,6 +587,7 @@ protected:
|
||||||
QString _script { ENTITY_ITEM_DEFAULT_SCRIPT }; /// the value of the script property
|
QString _script { ENTITY_ITEM_DEFAULT_SCRIPT }; /// the value of the script property
|
||||||
QString _loadedScript; /// the value of _script when the last preload signal was sent
|
QString _loadedScript; /// the value of _script when the last preload signal was sent
|
||||||
quint64 _scriptTimestamp { ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP }; /// the script loaded property used for forced reload
|
quint64 _scriptTimestamp { ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP }; /// the script loaded property used for forced reload
|
||||||
|
bool _scriptPreloadFinished { false };
|
||||||
|
|
||||||
QString _serverScripts;
|
QString _serverScripts;
|
||||||
/// keep track of time when _serverScripts property was last changed
|
/// keep track of time when _serverScripts property was last changed
|
||||||
|
@ -666,6 +670,7 @@ protected:
|
||||||
QUuid _sourceUUID; /// the server node UUID we came from
|
QUuid _sourceUUID; /// the server node UUID we came from
|
||||||
|
|
||||||
bool _clientOnly { false };
|
bool _clientOnly { false };
|
||||||
|
bool _transitingWithAvatar{ false };
|
||||||
QUuid _owningAvatarID;
|
QUuid _owningAvatarID;
|
||||||
|
|
||||||
// physics related changes from the network to suppress any duplicates and make
|
// physics related changes from the network to suppress any duplicates and make
|
||||||
|
|
|
@ -1216,7 +1216,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime, bool strictSemantics) const {
|
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime,
|
||||||
|
bool strictSemantics, EntityPsuedoPropertyFlags psueudoPropertyFlags) const {
|
||||||
|
|
||||||
// If strictSemantics is true and skipDefaults is false, then all and only those properties are copied for which the property flag
|
// If strictSemantics is true and skipDefaults is false, then all and only those properties are copied for which the property flag
|
||||||
// is included in _desiredProperties, or is one of the specially enumerated ALWAYS properties below.
|
// is included in _desiredProperties, or is one of the specially enumerated ALWAYS properties below.
|
||||||
// (There may be exceptions, but if so, they are bugs.)
|
// (There may be exceptions, but if so, they are bugs.)
|
||||||
|
@ -1224,26 +1226,39 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
QScriptValue properties = engine->newObject();
|
QScriptValue properties = engine->newObject();
|
||||||
EntityItemProperties defaultEntityProperties;
|
EntityItemProperties defaultEntityProperties;
|
||||||
|
|
||||||
|
const bool psuedoPropertyFlagsActive = psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::FlagsActive);
|
||||||
|
// Fix to skip the default return all mechanism, when psuedoPropertyFlagsActive
|
||||||
|
const bool psuedoPropertyFlagsButDesiredEmpty = psuedoPropertyFlagsActive && _desiredProperties.isEmpty();
|
||||||
|
|
||||||
if (_created == UNKNOWN_CREATED_TIME && !allowUnknownCreateTime) {
|
if (_created == UNKNOWN_CREATED_TIME && !allowUnknownCreateTime) {
|
||||||
// No entity properties can have been set so return without setting any default, zero property values.
|
// No entity properties can have been set so return without setting any default, zero property values.
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_idSet) {
|
if (_idSet && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ID))) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString());
|
||||||
}
|
}
|
||||||
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Type)) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(type, EntityTypes::getEntityTypeName(_type));
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(type, EntityTypes::getEntityTypeName(_type));
|
||||||
auto created = QDateTime::fromMSecsSinceEpoch(getCreated() / 1000.0f, Qt::UTC); // usec per msec
|
}
|
||||||
created.setTimeSpec(Qt::OffsetFromUTC);
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Created)) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(created, created.toString(Qt::ISODate));
|
auto created = QDateTime::fromMSecsSinceEpoch(getCreated() / 1000.0f, Qt::UTC); // usec per msec
|
||||||
|
created.setTimeSpec(Qt::OffsetFromUTC);
|
||||||
if ((!skipDefaults || _lifetime != defaultEntityProperties._lifetime) && !strictSemantics) {
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(created, created.toString(Qt::ISODate));
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
properties.setProperty("lastEdited", convertScriptValue(engine, _lastEdited));
|
if ((!skipDefaults || _lifetime != defaultEntityProperties._lifetime) && !strictSemantics) {
|
||||||
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Age)) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
||||||
|
}
|
||||||
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::AgeAsText)) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::LastEdited)) {
|
||||||
|
properties.setProperty("lastEdited", convertScriptValue(engine, _lastEdited));
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LAST_EDITED_BY, lastEditedBy);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LAST_EDITED_BY, lastEditedBy);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, position);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, position);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, dimensions);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, dimensions);
|
||||||
|
@ -1340,7 +1355,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
// Models only
|
// Models only
|
||||||
if (_type == EntityTypes::Model) {
|
if (_type == EntityTypes::Model) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL);
|
||||||
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
||||||
|
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
||||||
|
@ -1393,21 +1410,24 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
|
|
||||||
// Zones only
|
// Zones only
|
||||||
if (_type == EntityTypes::Zone) {
|
if (_type == EntityTypes::Zone) {
|
||||||
_keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
||||||
_ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
_keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
_ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
||||||
|
|
||||||
|
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_HAZE_MODE, hazeMode, getHazeModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_HAZE_MODE, hazeMode, getHazeModeAsString());
|
||||||
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
||||||
|
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BLOOM_MODE, bloomMode, getBloomModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BLOOM_MODE, bloomMode, getBloomModeAsString());
|
||||||
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
||||||
|
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_KEY_LIGHT_MODE, keyLightMode, getKeyLightModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_KEY_LIGHT_MODE, keyLightMode, getKeyLightModeAsString());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_LIGHT_MODE, ambientLightMode, getAmbientLightModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_LIGHT_MODE, ambientLightMode, getAmbientLightModeAsString());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SKYBOX_MODE, skyboxMode, getSkyboxModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SKYBOX_MODE, skyboxMode, getSkyboxModeAsString());
|
||||||
|
@ -1468,7 +1488,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
* @property {Vec3} center - The center of the AA box.
|
* @property {Vec3} center - The center of the AA box.
|
||||||
* @property {Vec3} dimensions - The dimensions of the AA box.
|
* @property {Vec3} dimensions - The dimensions of the AA box.
|
||||||
*/
|
*/
|
||||||
if (!skipDefaults && !strictSemantics) {
|
if (!skipDefaults && !strictSemantics &&
|
||||||
|
(!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::BoundingBox))) {
|
||||||
|
|
||||||
AABox aaBox = getAABox();
|
AABox aaBox = getAABox();
|
||||||
QScriptValue boundingBox = engine->newObject();
|
QScriptValue boundingBox = engine->newObject();
|
||||||
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
||||||
|
@ -1483,7 +1505,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
QString textureNamesStr = QJsonDocument::fromVariant(_textureNames).toJson();
|
QString textureNamesStr = QJsonDocument::fromVariant(_textureNames).toJson();
|
||||||
if (!skipDefaults && !strictSemantics) {
|
if (!skipDefaults && !strictSemantics && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::OriginalTextures))) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesStr); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesStr); // gettable, but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1509,7 +1531,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_ORIGIN_ID, cloneOriginID);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_ORIGIN_ID, cloneOriginID);
|
||||||
|
|
||||||
// Rendering info
|
// Rendering info
|
||||||
if (!skipDefaults && !strictSemantics) {
|
if (!skipDefaults && !strictSemantics &&
|
||||||
|
(!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::RenderInfo))) {
|
||||||
|
|
||||||
QScriptValue renderInfo = engine->newObject();
|
QScriptValue renderInfo = engine->newObject();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -1535,8 +1559,12 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: These properties should already have been set above.
|
// FIXME: These properties should already have been set above.
|
||||||
properties.setProperty("clientOnly", convertScriptValue(engine, getClientOnly()));
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ClientOnly)) {
|
||||||
properties.setProperty("owningAvatarID", convertScriptValue(engine, getOwningAvatarID()));
|
properties.setProperty("clientOnly", convertScriptValue(engine, getClientOnly()));
|
||||||
|
}
|
||||||
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::OwningAvatarID)) {
|
||||||
|
properties.setProperty("owningAvatarID", convertScriptValue(engine, getOwningAvatarID()));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME - I don't think these properties are supported any more
|
// FIXME - I don't think these properties are supported any more
|
||||||
//COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
//COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "EntityItemPropertiesMacros.h"
|
#include "EntityItemPropertiesMacros.h"
|
||||||
#include "EntityTypes.h"
|
#include "EntityTypes.h"
|
||||||
#include "EntityPropertyFlags.h"
|
#include "EntityPropertyFlags.h"
|
||||||
|
#include "EntityPsuedoPropertyFlags.h"
|
||||||
#include "LightEntityItem.h"
|
#include "LightEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
#include "ParticleEffectEntityItem.h"
|
#include "ParticleEffectEntityItem.h"
|
||||||
|
@ -86,7 +87,8 @@ public:
|
||||||
EntityTypes::EntityType getType() const { return _type; }
|
EntityTypes::EntityType getType() const { return _type; }
|
||||||
void setType(EntityTypes::EntityType type) { _type = type; }
|
void setType(EntityTypes::EntityType type) { _type = type; }
|
||||||
|
|
||||||
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime = false, bool strictSemantics = false) const;
|
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime = false,
|
||||||
|
bool strictSemantics = false, EntityPsuedoPropertyFlags psueudoPropertyFlags = EntityPsuedoPropertyFlags()) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool honorReadOnly);
|
virtual void copyFromScriptValue(const QScriptValue& object, bool honorReadOnly);
|
||||||
|
|
||||||
static QScriptValue entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags);
|
static QScriptValue entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags);
|
||||||
|
|
|
@ -155,7 +155,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \
|
||||||
if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \
|
if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \
|
||||||
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
||||||
QScriptValue V = convertScriptValue(engine, _##P); \
|
QScriptValue V = convertScriptValue(engine, _##P); \
|
||||||
properties.setProperty(#P, V); \
|
properties.setProperty(#P, V); \
|
||||||
|
@ -165,7 +165,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu
|
||||||
properties.setProperty(#P, G);
|
properties.setProperty(#P, G);
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, G) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, G) \
|
||||||
if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \
|
if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \
|
||||||
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
||||||
QScriptValue V = convertScriptValue(engine, G); \
|
QScriptValue V = convertScriptValue(engine, G); \
|
||||||
properties.setProperty(#P, V); \
|
properties.setProperty(#P, V); \
|
||||||
|
@ -173,7 +173,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu
|
||||||
|
|
||||||
// same as COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER but uses #X instead of #P in the setProperty() step
|
// same as COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER but uses #X instead of #P in the setProperty() step
|
||||||
#define COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, X, G) \
|
#define COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, X, G) \
|
||||||
if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \
|
if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \
|
||||||
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
||||||
QScriptValue V = convertScriptValue(engine, G); \
|
QScriptValue V = convertScriptValue(engine, G); \
|
||||||
properties.setProperty(#X, V); \
|
properties.setProperty(#X, V); \
|
||||||
|
|
41
libraries/entities/src/EntityPsuedoPropertyFlags.h
Normal file
41
libraries/entities/src/EntityPsuedoPropertyFlags.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// EntityPsuedoPropertyFlags.h
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Thijs Wenker on 9/18/18.
|
||||||
|
// Copyright 2018 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef hifi_EntityPsuedoPropertyFlag_h
|
||||||
|
#define hifi_EntityPsuedoPropertyFlag_h
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace EntityPsuedoPropertyFlag {
|
||||||
|
enum {
|
||||||
|
None = 0,
|
||||||
|
FlagsActive,
|
||||||
|
ID,
|
||||||
|
Type,
|
||||||
|
Created,
|
||||||
|
Age,
|
||||||
|
AgeAsText,
|
||||||
|
LastEdited,
|
||||||
|
BoundingBox,
|
||||||
|
OriginalTextures,
|
||||||
|
RenderInfo,
|
||||||
|
ClientOnly,
|
||||||
|
OwningAvatarID,
|
||||||
|
|
||||||
|
NumFlags
|
||||||
|
};
|
||||||
|
}
|
||||||
|
typedef std::bitset<EntityPsuedoPropertyFlag::NumFlags> EntityPsuedoPropertyFlags;
|
||||||
|
|
||||||
|
#endif // hifi_EntityPsuedoPropertyFlag_h
|
|
@ -42,7 +42,7 @@ const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}";
|
||||||
const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
|
const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
|
||||||
|
|
||||||
EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership) :
|
EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership) :
|
||||||
_entityTree(NULL),
|
_entityTree(nullptr),
|
||||||
_bidOnSimulationOwnership(bidOnSimulationOwnership)
|
_bidOnSimulationOwnership(bidOnSimulationOwnership)
|
||||||
{
|
{
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
@ -350,19 +350,19 @@ QUuid EntityScriptingInterface::cloneEntity(QUuid entityIDToClone) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity) {
|
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid entityID) {
|
||||||
EntityPropertyFlags noSpecificProperties;
|
const EntityPropertyFlags noSpecificProperties;
|
||||||
return getEntityProperties(identity, noSpecificProperties);
|
return getEntityProperties(entityID, noSpecificProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
|
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid entityID, EntityPropertyFlags desiredProperties) {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
bool scalesWithParent { false };
|
bool scalesWithParent { false };
|
||||||
EntityItemProperties results;
|
EntityItemProperties results;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->withReadLock([&] {
|
_entityTree->withReadLock([&] {
|
||||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||||
if (entity) {
|
if (entity) {
|
||||||
scalesWithParent = entity->getScalesWithParent();
|
scalesWithParent = entity->getScalesWithParent();
|
||||||
if (desiredProperties.getHasProperty(PROP_POSITION) ||
|
if (desiredProperties.getHasProperty(PROP_POSITION) ||
|
||||||
|
@ -397,6 +397,134 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
||||||
return convertPropertiesToScriptSemantics(results, scalesWithParent);
|
return convertPropertiesToScriptSemantics(results, scalesWithParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct EntityPropertiesResult {
|
||||||
|
EntityPropertiesResult(const EntityItemProperties& properties, bool scalesWithParent) :
|
||||||
|
properties(properties),
|
||||||
|
scalesWithParent(scalesWithParent) {
|
||||||
|
}
|
||||||
|
EntityPropertiesResult() = default;
|
||||||
|
EntityItemProperties properties;
|
||||||
|
bool scalesWithParent{ false };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Static method to make sure that we have the right script engine.
|
||||||
|
// Using sender() or QtScriptable::engine() does not work for classes used by multiple threads (script-engines)
|
||||||
|
QScriptValue EntityScriptingInterface::getMultipleEntityProperties(QScriptContext* context, QScriptEngine* engine) {
|
||||||
|
const int ARGUMENT_ENTITY_IDS = 0;
|
||||||
|
const int ARGUMENT_EXTENDED_DESIRED_PROPERTIES = 1;
|
||||||
|
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
const auto entityIDs = qScriptValueToValue<QVector<QUuid>>(context->argument(ARGUMENT_ENTITY_IDS));
|
||||||
|
return entityScriptingInterface->getMultipleEntityPropertiesInternal(engine, entityIDs, context->argument(ARGUMENT_EXTENDED_DESIRED_PROPERTIES));
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(QScriptEngine* engine, QVector<QUuid> entityIDs, const QScriptValue& extendedDesiredProperties) {
|
||||||
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
EntityPsuedoPropertyFlags psuedoPropertyFlags;
|
||||||
|
const auto readExtendedPropertyStringValue = [&](QScriptValue extendedProperty) {
|
||||||
|
const auto extendedPropertyString = extendedProperty.toString();
|
||||||
|
if (extendedPropertyString == "id") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::ID);
|
||||||
|
} else if (extendedPropertyString == "type") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::Type);
|
||||||
|
} else if (extendedPropertyString == "created") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::Created);
|
||||||
|
} else if (extendedPropertyString == "age") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::Age);
|
||||||
|
} else if (extendedPropertyString == "ageAsText") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::AgeAsText);
|
||||||
|
} else if (extendedPropertyString == "lastEdited") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::LastEdited);
|
||||||
|
} else if (extendedPropertyString == "boundingBox") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::BoundingBox);
|
||||||
|
} else if (extendedPropertyString == "originalTextures") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::OriginalTextures);
|
||||||
|
} else if (extendedPropertyString == "renderInfo") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::RenderInfo);
|
||||||
|
} else if (extendedPropertyString == "clientOnly") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::ClientOnly);
|
||||||
|
} else if (extendedPropertyString == "owningAvatarID") {
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::OwningAvatarID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (extendedDesiredProperties.isString()) {
|
||||||
|
readExtendedPropertyStringValue(extendedDesiredProperties);
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FlagsActive);
|
||||||
|
} else if (extendedDesiredProperties.isArray()) {
|
||||||
|
const quint32 length = extendedDesiredProperties.property("length").toInt32();
|
||||||
|
for (quint32 i = 0; i < length; i++) {
|
||||||
|
readExtendedPropertyStringValue(extendedDesiredProperties.property(i));
|
||||||
|
}
|
||||||
|
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FlagsActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityPropertyFlags desiredProperties = qScriptValueToValue<EntityPropertyFlags>(extendedDesiredProperties);
|
||||||
|
bool needsScriptSemantics = desiredProperties.getHasProperty(PROP_POSITION) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_ROTATION) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_POSITION) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_ROTATION) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_VELOCITY) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_DIMENSIONS);
|
||||||
|
if (needsScriptSemantics) {
|
||||||
|
// if we are explicitly getting position or rotation, we need parent information to make sense of them.
|
||||||
|
desiredProperties.setHasProperty(PROP_PARENT_ID);
|
||||||
|
desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX);
|
||||||
|
}
|
||||||
|
QVector<EntityPropertiesResult> resultProperties;
|
||||||
|
if (_entityTree) {
|
||||||
|
PROFILE_RANGE(script_entities, "EntityScriptingInterface::getMultipleEntityProperties>Obtaining Properties");
|
||||||
|
int i = 0;
|
||||||
|
const int lockAmount = 500;
|
||||||
|
int size = entityIDs.size();
|
||||||
|
while (i < size) {
|
||||||
|
_entityTree->withReadLock([&] {
|
||||||
|
for (int j = 0; j < lockAmount && i < size; ++i, ++j) {
|
||||||
|
const auto& entityID = entityIDs.at(i);
|
||||||
|
const EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||||
|
if (entity) {
|
||||||
|
if (psuedoPropertyFlags.none() && desiredProperties.isEmpty()) {
|
||||||
|
// these are left out of EntityItem::getEntityProperties so that localPosition and localRotation
|
||||||
|
// don't end up in json saves, etc. We still want them here, though.
|
||||||
|
EncodeBitstreamParams params; // unknown
|
||||||
|
desiredProperties = entity->getEntityProperties(params);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_POSITION);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_ROTATION);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_VELOCITY);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_ANGULAR_VELOCITY);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_DIMENSIONS);
|
||||||
|
psuedoPropertyFlags.set();
|
||||||
|
needsScriptSemantics = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto properties = entity->getProperties(desiredProperties, true);
|
||||||
|
EntityPropertiesResult result(properties, entity->getScalesWithParent());
|
||||||
|
resultProperties.append(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QScriptValue finalResult = engine->newArray(resultProperties.size());
|
||||||
|
quint32 i = 0;
|
||||||
|
if (needsScriptSemantics) {
|
||||||
|
PROFILE_RANGE(script_entities, "EntityScriptingInterface::getMultipleEntityProperties>Script Semantics");
|
||||||
|
foreach(const auto& result, resultProperties) {
|
||||||
|
finalResult.setProperty(i++, convertPropertiesToScriptSemantics(result.properties, result.scalesWithParent)
|
||||||
|
.copyToScriptValue(engine, false, false, false, psuedoPropertyFlags));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PROFILE_RANGE(script_entities, "EntityScriptingInterface::getMultipleEntityProperties>Skip Script Semantics");
|
||||||
|
foreach(const auto& result, resultProperties) {
|
||||||
|
finalResult.setProperty(i++, result.properties.copyToScriptValue(engine, false, false, false, psuedoPropertyFlags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalResult;
|
||||||
|
}
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
|
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,21 @@ public:
|
||||||
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard,
|
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard,
|
||||||
bool visibleOnly, bool collidableOnly);
|
bool visibleOnly, bool collidableOnly);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Get the properties of multiple entities.
|
||||||
|
* @function Entities.getMultipleEntityProperties
|
||||||
|
* @param {Uuid[]} entityIDs - The IDs of the entities to get the properties of.
|
||||||
|
* @param {string[]|string} [desiredProperties=[]] - Either string with property name or array of the names of the properties
|
||||||
|
* to get. If the array is empty, all properties are returned.
|
||||||
|
* @returns {Entities.EntityProperties[]} The properties of the entity if the entity can be found, otherwise an empty object.
|
||||||
|
* @example <caption>Retrieve the names of the nearby entities</caption>
|
||||||
|
* var SEARCH_RADIUS = 50; // meters
|
||||||
|
* var entityIds = Entities.findEntities(MyAvatar.position, SEARCH_RADIUS);
|
||||||
|
* var propertySets = Entities.getMultipleEntityProperties(entityIds, "name");
|
||||||
|
* print("Nearby entity names: " + JSON.stringify(propertySets));
|
||||||
|
*/
|
||||||
|
static QScriptValue getMultipleEntityProperties(QScriptContext* context, QScriptEngine* engine);
|
||||||
|
QScriptValue getMultipleEntityPropertiesInternal(QScriptEngine* engine, QVector<QUuid> entityIDs, const QScriptValue& extendedDesiredProperties);
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -270,7 +285,7 @@ public slots:
|
||||||
* print("Entity color: " + JSON.stringify(properties.color));
|
* print("Entity color: " + JSON.stringify(properties.color));
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
||||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties);
|
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID, EntityPropertyFlags desiredProperties);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Update an entity with specified properties.
|
* Update an entity with specified properties.
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#define hifi_EntityTypes_h
|
#define hifi_EntityTypes_h
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
|
@ -69,8 +69,8 @@ void LightEntityItem::dimensionsChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties LightEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties LightEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,9 @@ LineEntityItem::LineEntityItem(const EntityItemID& entityItemID) :
|
||||||
_type = EntityTypes::Line;
|
_type = EntityTypes::Line;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties LineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties LineEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
|
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
|
|
|
@ -23,7 +23,7 @@ class LineEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -31,8 +31,8 @@ MaterialEntityItem::~MaterialEntityItem() {
|
||||||
removeMaterial();
|
removeMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties MaterialEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingMode, getMaterialMappingMode);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingMode, getMaterialMappingMode);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(priority, getPriority);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(priority, getPriority);
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
bool needsToCallUpdate() const override { return true; }
|
bool needsToCallUpdate() const override { return true; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -54,8 +54,8 @@ void ModelEntityItem::setTextures(const QString& textures) {
|
||||||
_textures = textures;
|
_textures = textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties ModelEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -408,8 +408,8 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
||||||
|
|
|
@ -210,7 +210,7 @@ public:
|
||||||
ParticleEffectEntityItem(const EntityItemID& entityItemID);
|
ParticleEffectEntityItem(const EntityItemID& entityItemID);
|
||||||
|
|
||||||
// methods for getting/setting all properties of this entity
|
// methods for getting/setting all properties of this entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -36,9 +36,9 @@ PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : Entit
|
||||||
_type = EntityTypes::PolyLine;
|
_type = EntityTypes::PolyLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties PolyLineEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
QWriteLocker lock(&_quadReadWriteLock);
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
|
|
|
@ -23,7 +23,7 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -113,8 +113,8 @@ glm::vec3 PolyVoxEntityItem::getVoxelVolumeSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties PolyVoxEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties PolyVoxEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelData, getVoxelData);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelData, getVoxelData);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelSurfaceStyle, getVoxelSurfaceStyle);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelSurfaceStyle, getVoxelSurfaceStyle);
|
||||||
|
|
|
@ -23,7 +23,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -115,8 +115,8 @@ ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem(
|
||||||
_material = std::make_shared<graphics::Material>();
|
_material = std::make_shared<graphics::Material>();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ShapeEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
properties.setShape(entity::stringFromShape(getShape()));
|
properties.setShape(entity::stringFromShape(getShape()));
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
//ALLOW_INSTANTIATION
|
//ALLOW_INSTANTIATION
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
bool setProperties(const EntityItemProperties& properties) override;
|
bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -46,8 +46,8 @@ void TextEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties TextEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -41,8 +41,8 @@ void WebEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties WebEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(sourceUrl, getSourceUrl);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(sourceUrl, getSourceUrl);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dpi, getDPI);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dpi, getDPI);
|
||||||
return properties;
|
return properties;
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||||
|
|
|
@ -45,8 +45,8 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID) : EntityItem(en
|
||||||
_visuallyReady = false;
|
_visuallyReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties ZoneEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
// Contain QString properties, must be synchronized
|
// Contain QString properties, must be synchronized
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
||||||
|
|
|
@ -1923,7 +1923,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
};
|
};
|
||||||
|
|
||||||
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
|
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
|
||||||
glm::vec3 defaultCapsuleAxis(0.0f, 1.0f, 0.0f);
|
|
||||||
for (int i = 0; i < geometry.joints.size(); ++i) {
|
for (int i = 0; i < geometry.joints.size(); ++i) {
|
||||||
FBXJoint& joint = geometry.joints[i];
|
FBXJoint& joint = geometry.joints[i];
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct GLFilterMode {
|
||||||
|
|
||||||
class GLTextureTransferEngine {
|
class GLTextureTransferEngine {
|
||||||
public:
|
public:
|
||||||
|
virtual ~GLTextureTransferEngine() {}
|
||||||
using Pointer = std::shared_ptr<GLTextureTransferEngine>;
|
using Pointer = std::shared_ptr<GLTextureTransferEngine>;
|
||||||
/// Called once per frame to perform any require memory management or transfer work
|
/// Called once per frame to perform any require memory management or transfer work
|
||||||
virtual void manageMemory() = 0;
|
virtual void manageMemory() = 0;
|
||||||
|
|
|
@ -295,7 +295,6 @@ GL41VariableAllocationTexture::GL41VariableAllocationTexture(const std::weak_ptr
|
||||||
_maxAllocatedMip = _populatedMip = mipLevels;
|
_maxAllocatedMip = _populatedMip = mipLevels;
|
||||||
_minAllocatedMip = texture.minAvailableMipLevel();
|
_minAllocatedMip = texture.minAvailableMipLevel();
|
||||||
|
|
||||||
uvec3 mipDimensions;
|
|
||||||
for (uint16_t mip = _minAllocatedMip; mip < mipLevels; ++mip) {
|
for (uint16_t mip = _minAllocatedMip; mip < mipLevels; ++mip) {
|
||||||
if (glm::all(glm::lessThanEqual(texture.evalMipDimensions(mip), INITIAL_MIP_TRANSFER_DIMENSIONS))) {
|
if (glm::all(glm::lessThanEqual(texture.evalMipDimensions(mip), INITIAL_MIP_TRANSFER_DIMENSIONS))) {
|
||||||
_maxAllocatedMip = _populatedMip = mip;
|
_maxAllocatedMip = _populatedMip = mip;
|
||||||
|
|
|
@ -85,7 +85,6 @@ GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend
|
||||||
_maxAllocatedMip = _populatedMip = mipLevels;
|
_maxAllocatedMip = _populatedMip = mipLevels;
|
||||||
_minAllocatedMip = texture.minAvailableMipLevel();
|
_minAllocatedMip = texture.minAvailableMipLevel();
|
||||||
|
|
||||||
uvec3 mipDimensions;
|
|
||||||
for (uint16_t mip = _minAllocatedMip; mip < mipLevels; ++mip) {
|
for (uint16_t mip = _minAllocatedMip; mip < mipLevels; ++mip) {
|
||||||
if (glm::all(glm::lessThanEqual(texture.evalMipDimensions(mip), INITIAL_MIP_TRANSFER_DIMENSIONS))) {
|
if (glm::all(glm::lessThanEqual(texture.evalMipDimensions(mip), INITIAL_MIP_TRANSFER_DIMENSIONS))) {
|
||||||
_maxAllocatedMip = _populatedMip = mip;
|
_maxAllocatedMip = _populatedMip = mip;
|
||||||
|
|
|
@ -118,10 +118,12 @@ public:
|
||||||
uint8 _function = LESS;
|
uint8 _function = LESS;
|
||||||
uint8 _writeMask = true;
|
uint8 _writeMask = true;
|
||||||
uint8 _enabled = false;
|
uint8 _enabled = false;
|
||||||
uint8 _spare = 0;
|
uint8 _spare = 0; // _spare is here to to affect alignment
|
||||||
public:
|
public:
|
||||||
DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) :
|
DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) :
|
||||||
_function(func), _writeMask(writeMask), _enabled(enabled) {}
|
_function(func), _writeMask(writeMask), _enabled(enabled) {
|
||||||
|
(void)_spare; // to avoid unusued variable warning
|
||||||
|
}
|
||||||
|
|
||||||
bool isEnabled() const { return _enabled != 0; }
|
bool isEnabled() const { return _enabled != 0; }
|
||||||
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
||||||
|
|
|
@ -445,5 +445,3 @@ void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
|
||||||
|
|
||||||
Q_UNUSED(metaTypeIds);
|
Q_UNUSED(metaTypeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "GraphicsScriptingInterface.moc"
|
|
||||||
|
|
|
@ -401,6 +401,3 @@ scriptable::ScriptableMesh::~ScriptableMesh() {
|
||||||
#endif
|
#endif
|
||||||
strongMesh.reset();
|
strongMesh.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "ScriptableMesh.moc"
|
|
||||||
|
|
||||||
|
|
|
@ -240,5 +240,3 @@ glm::uint32 scriptable::ScriptableModel::forEachVertexAttribute(QScriptValue cal
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ScriptableModel.moc"
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ protected:
|
||||||
class InputDevice : public controller::InputDevice {
|
class InputDevice : public controller::InputDevice {
|
||||||
public:
|
public:
|
||||||
InputDevice() : controller::InputDevice("Keyboard") {}
|
InputDevice() : controller::InputDevice("Keyboard") {}
|
||||||
|
virtual ~InputDevice() {}
|
||||||
private:
|
private:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
|
|
||||||
Geometry() = default;
|
Geometry() = default;
|
||||||
Geometry(const Geometry& geometry);
|
Geometry(const Geometry& geometry);
|
||||||
|
virtual ~Geometry() {}
|
||||||
|
|
||||||
// Immutable over lifetime
|
// Immutable over lifetime
|
||||||
using GeometryMeshes = std::vector<std::shared_ptr<const graphics::Mesh>>;
|
using GeometryMeshes = std::vector<std::shared_ptr<const graphics::Mesh>>;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue