Merge branch 'master' of https://github.com/highfidelity/hifi into fixGrabWebSurface-case-16192

This commit is contained in:
Wayne Chen 2018-07-17 11:54:15 -07:00
commit 2c16c6579f
57 changed files with 354 additions and 209 deletions

View file

@ -4,6 +4,7 @@ import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.Editable; import android.text.Editable;
@ -32,6 +33,7 @@ public class HomeFragment extends Fragment {
private OnHomeInteractionListener mListener; private OnHomeInteractionListener mListener;
private SwipeRefreshLayout mSwipeRefreshLayout;
public native String nativeGetLastLocation(); public native String nativeGetLastLocation();
@ -57,6 +59,7 @@ public class HomeFragment extends Fragment {
View rootView = inflater.inflate(R.layout.fragment_home, container, false); View rootView = inflater.inflate(R.layout.fragment_home, container, false);
searchNoResultsView = rootView.findViewById(R.id.searchNoResultsView); searchNoResultsView = rootView.findViewById(R.id.searchNoResultsView);
mSwipeRefreshLayout = rootView.findViewById(R.id.swipeRefreshLayout);
mDomainsView = rootView.findViewById(R.id.rvDomains); mDomainsView = rootView.findViewById(R.id.rvDomains);
int numberOfColumns = 1; int numberOfColumns = 1;
@ -76,12 +79,14 @@ public class HomeFragment extends Fragment {
searchNoResultsView.setText(R.string.search_no_results); searchNoResultsView.setText(R.string.search_no_results);
searchNoResultsView.setVisibility(View.VISIBLE); searchNoResultsView.setVisibility(View.VISIBLE);
mDomainsView.setVisibility(View.GONE); mDomainsView.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
} }
@Override @Override
public void onNonEmptyAdapter() { public void onNonEmptyAdapter() {
searchNoResultsView.setVisibility(View.GONE); searchNoResultsView.setVisibility(View.GONE);
mDomainsView.setVisibility(View.VISIBLE); mDomainsView.setVisibility(View.VISIBLE);
mSwipeRefreshLayout.setRefreshing(false);
} }
@Override @Override
@ -104,7 +109,7 @@ public class HomeFragment extends Fragment {
@Override @Override
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
mDomainAdapter.loadDomains(editable.toString()); mDomainAdapter.loadDomains(editable.toString(), false);
if (editable.length() > 0) { if (editable.length() > 0) {
mSearchIconView.setVisibility(View.GONE); mSearchIconView.setVisibility(View.GONE);
mClearSearch.setVisibility(View.VISIBLE); mClearSearch.setVisibility(View.VISIBLE);
@ -130,6 +135,13 @@ public class HomeFragment extends Fragment {
mClearSearch.setOnClickListener(view -> onSearchClear(view)); mClearSearch.setOnClickListener(view -> onSearchClear(view));
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mDomainAdapter.loadDomains(mSearchView.getText().toString(), true);
}
});
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
return rootView; return rootView;

View file

@ -10,7 +10,7 @@ import io.highfidelity.hifiinterface.view.DomainAdapter;
public interface DomainProvider { public interface DomainProvider {
void retrieve(String filterText, DomainCallback domainCallback); void retrieve(String filterText, DomainCallback domainCallback, boolean forceRefresh);
interface DomainCallback { interface DomainCallback {
void retrieveOk(List<DomainAdapter.Domain> domain); void retrieveOk(List<DomainAdapter.Domain> domain);

View file

@ -49,8 +49,8 @@ public class UserStoryDomainProvider implements DomainProvider {
} }
@Override @Override
public synchronized void retrieve(String filterText, DomainCallback domainCallback) { public synchronized void retrieve(String filterText, DomainCallback domainCallback, boolean forceRefresh) {
if (!startedToGetFromAPI) { if (!startedToGetFromAPI || forceRefresh) {
startedToGetFromAPI = true; startedToGetFromAPI = true;
fillDestinations(filterText, domainCallback); fillDestinations(filterText, domainCallback);
} else { } else {
@ -72,6 +72,7 @@ public class UserStoryDomainProvider implements DomainProvider {
allStories.clear(); allStories.clear();
getUserStoryPage(1, allStories, null, getUserStoryPage(1, allStories, null,
ex -> { ex -> {
suggestions.clear();
allStories.forEach(userStory -> { allStories.forEach(userStory -> {
if (taggedStoriesIds.contains(userStory.id)) { if (taggedStoriesIds.contains(userStory.id)) {
userStory.tagFound = true; userStory.tagFound = true;

View file

@ -42,14 +42,14 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
mProtocol = protocol; mProtocol = protocol;
mLastLocation = lastLocation; mLastLocation = lastLocation;
domainProvider = new UserStoryDomainProvider(mProtocol); domainProvider = new UserStoryDomainProvider(mProtocol);
loadDomains(""); loadDomains("", true);
} }
public void setListener(AdapterListener adapterListener) { public void setListener(AdapterListener adapterListener) {
mAdapterListener = adapterListener; mAdapterListener = adapterListener;
} }
public void loadDomains(String filterText) { public void loadDomains(String filterText, boolean forceRefresh) {
domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() { domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() {
@Override @Override
public void retrieveOk(List<Domain> domain) { public void retrieveOk(List<Domain> domain) {
@ -76,7 +76,7 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
Log.e("DOMAINS", message, e); Log.e("DOMAINS", message, e);
if (mAdapterListener != null) mAdapterListener.onError(e, message); if (mAdapterListener != null) mAdapterListener.onError(e, message);
} }
}); }, forceRefresh);
} }
private void overrideDefaultThumbnails(List<Domain> domain) { private void overrideDefaultThumbnails(List<Domain> domain) {

View file

@ -63,13 +63,18 @@
android:visibility="gone" android:visibility="gone"
/> />
<android.support.v7.widget.RecyclerView <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/rvDomains" android:id="@+id/swipeRefreshLayout"
app:layout_constraintTop_toBottomOf="@id/searchView" app:layout_constraintTop_toBottomOf="@id/searchView"
app:layout_constraintBottom_toBottomOf="@id/contentHomeRoot" app:layout_constraintBottom_toBottomOf="@id/contentHomeRoot"
app:layout_constraintStart_toStartOf="@id/contentHomeRoot" app:layout_constraintStart_toStartOf="@id/contentHomeRoot"
app:layout_constraintEnd_toEndOf="@id/contentHomeRoot" app:layout_constraintEnd_toEndOf="@id/contentHomeRoot"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" /> android:layout_height="0dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvDomains"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME GifCreator)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/GifCreator.zip URL https://public.highfidelity.com/dependencies/GifCreator.zip
URL_MD5 8ac8ef5196f47c658dce784df5ecdb70 URL_MD5 8ac8ef5196f47c658dce784df5ecdb70
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -17,7 +17,7 @@ if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.26.0_public.zip URL https://public.highfidelity.com/dependencies/ovr_sdk_win_1.26.0_public.zip
URL_MD5 06804ff9727b910dcd04a37c800053b5 URL_MD5 06804ff9727b910dcd04a37c800053b5
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
@ -38,7 +38,7 @@ elseif(APPLE)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://static.oculus.com/sdk-downloads/ovr_sdk_macos_0.5.0.1.tar.gz URL https://public.highfidelity.com/dependencies/ovr_sdk_macos_0.5.0.1.tar.gz
URL_MD5 0a0785a04fb285f64f62267388344ad6 URL_MD5 0a0785a04fb285f64f62267388344ad6
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -9,7 +9,7 @@ if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/OVRPlatformSDK_v1.10.0.zip URL https://public.highfidelity.com/dependencies/OVRPlatformSDK_v1.10.0.zip
URL_MD5 e6c8264af16d904e6506acd5172fa0a9 URL_MD5 e6c8264af16d904e6506acd5172fa0a9
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -5,7 +5,7 @@ include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
#URL https://github.com/boostorg/config/archive/boost-1.58.0.zip #URL https://github.com/boostorg/config/archive/boost-1.58.0.zip
URL http://hifi-public.s3.amazonaws.com/dependencies/config-boost-1.58.0.zip URL https://public.highfidelity.com/dependencies/config-boost-1.58.0.zip
URL_MD5 42fa673bae2b7645a22736445e80eb8d URL_MD5 42fa673bae2b7645a22736445e80eb8d
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -17,7 +17,7 @@ include(ExternalProject)
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.88.tgz URL https://public.highfidelity.com/dependencies/bullet-2.88.tgz
URL_MD5 0a6876607ebe83e227427215f15946fd URL_MD5 0a6876607ebe83e227427215f15946fd
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0 -DUSE_DX11=0 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0 -DUSE_DX11=0
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1
@ -28,7 +28,7 @@ if (WIN32)
else () else ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.88.tgz URL https://public.highfidelity.com/dependencies/bullet-2.88.tgz
URL_MD5 0a6876607ebe83e227427215f15946fd URL_MD5 0a6876607ebe83e227427215f15946fd
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -6,7 +6,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://public.highfidelity.com/dependencies/crashpad_062317.1.zip URL https://public.highfidelity.com/dependencies/crashpad_062317.1.zip
URL_MD5 9c84b77f5f23daf939da1371825ed2b1 URL_MD5 9c84b77f5f23daf939da1371825ed2b1
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
@ -25,7 +25,7 @@ if (WIN32)
elseif (APPLE) elseif (APPLE)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://public.highfidelity.com/dependencies/crashpad_mac_070318.zip URL https://public.highfidelity.com/dependencies/crashpad_mac_070318.zip
URL_MD5 ba1501dc163591ac2d1be74946967e2a URL_MD5 ba1501dc163591ac2d1be74946967e2a
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -11,7 +11,7 @@ endif ()
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/draco-1.1.0.zip URL https://public.highfidelity.com/dependencies/draco-1.1.0.zip
URL_MD5 208f8b04c91d5f1c73d731a3ea37c5bb URL_MD5 208f8b04c91d5f1c73d731a3ea37c5bb
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS} CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -15,7 +15,7 @@ include(ExternalProject)
# that would override CMAKE_CXX_FLAGS # that would override CMAKE_CXX_FLAGS
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/etc2comp-patched.zip URL https://public.highfidelity.com/dependencies/etc2comp-patched.zip
URL_MD5 4c96153eb179acbe619e3d99d3330595 URL_MD5 4c96153eb179acbe619e3d99d3330595
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} ${EXTRA_CMAKE_FLAGS} CMAKE_ARGS ${ANDROID_CMAKE_ARGS} ${EXTRA_CMAKE_FLAGS}
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad32es.zip URL https://public.highfidelity.com/dependencies/glad/glad32es.zip
URL_MD5 6a641d8c49dee4c895fa59315f5682a6 URL_MD5 6a641d8c49dee4c895fa59315f5682a6
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad41.zip URL https://public.highfidelity.com/dependencies/glad/glad41.zip
URL_MD5 1324eeec33abe91e67d19ae551ba624d URL_MD5 1324eeec33abe91e67d19ae551ba624d
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad45.zip URL https://public.highfidelity.com/dependencies/glad/glad45.zip
URL_MD5 cfb19b3cb5b2f8f1d1669fb3150e5f05 URL_MD5 cfb19b3cb5b2f8f1d1669fb3150e5f05
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME gli)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/gli-0.8.1.0.zip URL https://public.highfidelity.com/dependencies/gli-0.8.1.0.zip
URL_MD5 00c990f59c12bbf367956ef399d6f798 URL_MD5 00c990f59c12bbf367956ef399d6f798
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME glm)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/glm-0.9.8.5-patched.zip URL https://public.highfidelity.com/dependencies/glm-0.9.8.5-patched.zip
URL_MD5 7d39ecc1cea275427534c3cfd6dd63f0 URL_MD5 7d39ecc1cea275427534c3cfd6dd63f0
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTERNAL_ARGS} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTERNAL_ARGS}

View file

@ -6,16 +6,16 @@ set(EXTERNAL_NAME hifiAudioCodec)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32) if (WIN32)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-win-2.0.zip) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-win-2.0.zip)
set(DOWNLOAD_MD5 9199d4dbd6b16bed736b235efe980e67) set(DOWNLOAD_MD5 9199d4dbd6b16bed736b235efe980e67)
elseif (APPLE) elseif (APPLE)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-mac-2.0.zip) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-mac-2.0.zip)
set(DOWNLOAD_MD5 21649881e7d5dc94f922179be96f76ba) set(DOWNLOAD_MD5 21649881e7d5dc94f922179be96f76ba)
elseif (ANDROID) elseif (ANDROID)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-android-2.0.zip) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-android-2.0.zip)
set(DOWNLOAD_MD5 aef2a852600d498d58aa586668191683) set(DOWNLOAD_MD5 aef2a852600d498d58aa586668191683)
elseif (UNIX) elseif (UNIX)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux-2.0.zip) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-linux-2.0.zip)
set(DOWNLOAD_MD5 67fb7755f9bcafb98a9fceea53bc7481) set(DOWNLOAD_MD5 67fb7755f9bcafb98a9fceea53bc7481)
else() else()
return() return()

View file

@ -4,7 +4,7 @@ set(EXTERNAL_NAME neuron)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.2.zip") set(NEURON_URL "https://public.highfidelity.com/dependencies/neuron_datareader_b.12.2.zip")
set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca") set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca")
ExternalProject_Add(${EXTERNAL_NAME} ExternalProject_Add(${EXTERNAL_NAME}

View file

@ -8,7 +8,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip URL https://public.highfidelity.com/dependencies/nvtt-win-2.1.0.hifi.zip
URL_MD5 10da01cf601f88f6dc12a6bc13c89136 URL_MD5 10da01cf601f88f6dc12a6bc13c89136
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
@ -29,7 +29,7 @@ else ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi-83462e4.zip URL https://public.highfidelity.com/dependencies/nvidia-texture-tools-2.1.0.hifi-83462e4.zip
URL_MD5 602776e08515b54bfa1b8dc455003f0f URL_MD5 602776e08515b54bfa1b8dc455003f0f
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -7,7 +7,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://github.com/ValveSoftware/openvr/archive/v1.0.6.zip URL https://public.highfidelity.com/dependencies/openvr-1.0.6.zip
URL_MD5 f6892cd3a3078f505d03b4297f5a1951 URL_MD5 f6892cd3a3078f505d03b4297f5a1951
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME polyvox)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/polyvox-master-2015-7-15.zip URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip
URL_MD5 9ec6323b87e849ae36e562ae1c7494a9 URL_MD5 9ec6323b87e849ae36e562ae1c7494a9
CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -13,7 +13,7 @@ endif ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/quazip-0.7.3.zip URL https://public.highfidelity.com/dependencies/quazip-0.7.3.zip
URL_MD5 ed03754d39b9da1775771819b8001d45 URL_MD5 ed03754d39b9da1775771819b8001d45
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} CMAKE_ARGS ${QUAZIP_CMAKE_ARGS}

View file

@ -7,7 +7,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-devel-2.0.3-VC.zip URL https://public.highfidelity.com/dependencies/SDL2-devel-2.0.3-VC.zip
URL_MD5 30a333bcbe94bc5016e8799c73e86233 URL_MD5 30a333bcbe94bc5016e8799c73e86233
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
@ -18,7 +18,8 @@ elseif (APPLE)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3.zip URL https://public.highfidelity.com/dependencies/SDL2-2.0.3.zip
URL_MD5 55f1eae5142d20db11c844d8d4d6deed
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DVIDEO_OPENGL=OFF CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DVIDEO_OPENGL=OFF
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1
@ -49,7 +50,7 @@ else ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://www.libsdl.org/release/SDL2-2.0.3.tar.gz URL https://public.highfidelity.com/dependencies/SDL2-2.0.3.tar.gz
URL_MD5 fe6c61d2e9df9ef570e7e80c6e822537 URL_MD5 fe6c61d2e9df9ef570e7e80c6e822537
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -4,15 +4,15 @@ set(EXTERNAL_NAME sixense)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
#set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_062612.zip") #set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_062612.zip")
#set(SIXENSE_URL_MD5 "10cc8dc470d2ac1244a88cf04bc549cc") #set(SIXENSE_URL_MD5 "10cc8dc470d2ac1244a88cf04bc549cc")
#set(SIXENSE_NEW_LAYOUT 0) #set(SIXENSE_NEW_LAYOUT 0)
set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip") set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_071615.zip")
set(SIXENSE_URL_MD5 "752a3901f334124e9cffc2ba4136ef7d") set(SIXENSE_URL_MD5 "752a3901f334124e9cffc2ba4136ef7d")
set(SIXENSE_NEW_LAYOUT 1) set(SIXENSE_NEW_LAYOUT 1)
#set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_102215.zip") #set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_102215.zip")
#set(SIXENSE_URL_MD5 "93c3a6795cce777a0f472b09532935f1") #set(SIXENSE_URL_MD5 "93c3a6795cce777a0f472b09532935f1")
#set(SIXENSE_NEW_LAYOUT 1) #set(SIXENSE_NEW_LAYOUT 1)

View file

@ -4,7 +4,7 @@ set(EXTERNAL_NAME steamworks)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(STEAMWORKS_URL "https://s3.amazonaws.com/hifi-public/dependencies/steamworks_sdk_137.zip") set(STEAMWORKS_URL "https://public.highfidelity.com/dependencies/steamworks_sdk_137.zip")
set(STEAMWORKS_URL_MD5 "95ba9d0e3ddc04f8a8be17d2da806cbb") set(STEAMWORKS_URL_MD5 "95ba9d0e3ddc04f8a8be17d2da806cbb")
ExternalProject_Add( ExternalProject_Add(

View file

@ -3,13 +3,13 @@ set(EXTERNAL_NAME tbb)
include(ExternalProject) include(ExternalProject)
if (WIN32) if (WIN32)
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb2017_20170604oss_win_slim.zip) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_win_slim.zip)
set(DOWNLOAD_MD5 065934458e3db88397f3d10e7eea536c) set(DOWNLOAD_MD5 065934458e3db88397f3d10e7eea536c)
elseif (APPLE) elseif (APPLE)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb2017_20170604oss_mac_slim.tar.gz) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_mac_slim.tar.gz)
set(DOWNLOAD_MD5 62bde626b396f8e1a85c6a8ded1d8105) set(DOWNLOAD_MD5 62bde626b396f8e1a85c6a8ded1d8105)
else () else ()
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb2017_20170604oss_lin_slim.tar.gz) set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_lin_slim.tar.gz)
set(DOWNLOAD_MD5 2a5c721f40fa3503ffc12c18dd00011c) set(DOWNLOAD_MD5 2a5c721f40fa3503ffc12c18dd00011c)
endif () endif ()

View file

@ -7,7 +7,7 @@ endif ()
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/v-hacd-master.zip URL https://public.highfidelity.com/dependencies/v-hacd-master.zip
URL_MD5 3bfc94f8dd3dfbfe8f4dc088f4820b3e URL_MD5 3bfc94f8dd3dfbfe8f4dc088f4820b3e
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -6,7 +6,7 @@ if (WIN32)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/qtaudio_wasapi10.zip URL https://public.highfidelity.com/dependencies/qtaudio_wasapi10.zip
URL_MD5 4f40e49715a420fb67b45b9cee19052c URL_MD5 4f40e49715a420fb67b45b9cee19052c
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""

View file

@ -5,7 +5,8 @@ include(ExternalProject)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/zlib128.zip URL https://public.highfidelity.com/dependencies/zlib128.zip
URL_MD5 126f8676442ffbd97884eb4d6f32afb4
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1

View file

@ -46,7 +46,6 @@ FocusScope {
hoverEnabled: true hoverEnabled: true
visible: true visible: true
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.
textRole: "text"
function previousItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count - 1) % comboBox.count; } function previousItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count - 1) % comboBox.count; }
function nextItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count + 1) % comboBox.count; } function nextItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count + 1) % comboBox.count; }

View file

@ -1108,7 +1108,7 @@ Rectangle {
function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml
var data = optionalData || nearbyUserModelData, length = data.length; var data = optionalData || nearbyUserModelData, length = data.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (data[i].sessionId === sessionId) { if (data[i].sessionId === sessionId.toString()) {
return i; return i;
} }
} }
@ -1120,7 +1120,7 @@ Rectangle {
var data = message.params; var data = message.params;
var index = -1; var index = -1;
iAmAdmin = Users.canKick; iAmAdmin = Users.canKick;
index = findNearbySessionIndex('', data); index = findNearbySessionIndex("", data);
if (index !== -1) { if (index !== -1) {
myData = data[index]; myData = data[index];
data.splice(index, 1); data.splice(index, 1);
@ -1197,8 +1197,8 @@ Rectangle {
for (var userId in message.params) { for (var userId in message.params) {
var audioLevel = message.params[userId][0]; var audioLevel = message.params[userId][0];
var avgAudioLevel = message.params[userId][1]; var avgAudioLevel = message.params[userId][1];
// If the userId is 0, we're updating "myData". // If the userId is "", we're updating "myData".
if (userId == 0) { if (userId === "") {
myData.audioLevel = audioLevel; myData.audioLevel = audioLevel;
myCard.audioLevel = audioLevel; // Defensive programming myCard.audioLevel = audioLevel; // Defensive programming
myData.avgAudioLevel = avgAudioLevel; myData.avgAudioLevel = avgAudioLevel;

View file

@ -125,7 +125,6 @@ Rectangle {
id: wearablesCombobox id: wearablesCombobox
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
comboBox.textRole: "text"
model: ListModel { model: ListModel {
function findIndexById(id) { function findIndexById(id) {

View file

@ -328,7 +328,15 @@ Item {
item.buttonColor = "#E2334D"; item.buttonColor = "#E2334D";
item.buttonClicked = function() { item.buttonClicked = function() {
sendToPurchases({ method: 'flipCard', closeAll: true }); sendToPurchases({ method: 'flipCard', closeAll: true });
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl}); sendToPurchases({
method: 'updateItemClicked',
itemId: root.itemId,
itemEdition: root.itemEdition,
upgradeUrl: root.upgradeUrl,
itemHref: root.itemHref,
itemType: root.itemType,
isInstalled: root.isInstalled
});
} }
} }
} }

View file

@ -706,7 +706,23 @@ Rectangle {
} }
} }
} else if (msg.method === "updateItemClicked") { } else if (msg.method === "updateItemClicked") {
sendToScript(msg); if (msg.itemType === "app" && msg.isInstalled) {
lightboxPopup.titleText = "Uninstall App";
lightboxPopup.bodyText = "The app that you are trying to update is installed.<br><br>" +
"If you proceed, the current version of the app will be uninstalled.";
lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = function() {
Commerce.uninstallApp(msg.itemHref);
sendToScript(msg);
};
lightboxPopup.visible = true;
} else {
sendToScript(msg);
}
} else if (msg.method === "giftAsset") { } else if (msg.method === "giftAsset") {
sendAsset.assetName = msg.itemName; sendAsset.assetName = msg.itemName;
sendAsset.assetCertID = msg.certId; sendAsset.assetCertID = msg.certId;

View file

@ -14,6 +14,7 @@
#include <string> #include <string>
#include <QScriptEngine> #include <QScriptEngine>
#include <QtCore/QJsonDocument>
#include "AvatarLogging.h" #include "AvatarLogging.h"
@ -668,3 +669,49 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV
DependencyManager::get<NodeList>()->broadcastToNodes(std::move(packet), NodeSet() << NodeType::AvatarMixer); DependencyManager::get<NodeList>()->broadcastToNodes(std::move(packet), NodeSet() << NodeType::AvatarMixer);
} }
} }
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
QJsonArray palData;
auto avatarMap = getHashCopy();
AvatarHash::iterator itr = avatarMap.begin();
while (itr != avatarMap.end()) {
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(*itr);
QString currentSessionUUID = avatar->getSessionUUID().toString();
if (specificAvatarIdentifiers.isEmpty() || specificAvatarIdentifiers.contains(currentSessionUUID)) {
QJsonObject thisAvatarPalData;
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
if (currentSessionUUID == myAvatar->getSessionUUID().toString()) {
currentSessionUUID = "";
}
thisAvatarPalData.insert("sessionUUID", currentSessionUUID);
thisAvatarPalData.insert("sessionDisplayName", avatar->getSessionDisplayName());
thisAvatarPalData.insert("audioLoudness", avatar->getAudioLoudness());
thisAvatarPalData.insert("isReplicated", avatar->getIsReplicated());
glm::vec3 position = avatar->getWorldPosition();
QJsonObject jsonPosition;
jsonPosition.insert("x", position.x);
jsonPosition.insert("y", position.y);
jsonPosition.insert("z", position.z);
thisAvatarPalData.insert("position", jsonPosition);
float palOrbOffset = 0.2f;
int headIndex = avatar->getJointIndex("Head");
if (headIndex > 0) {
glm::vec3 jointTranslation = avatar->getAbsoluteJointTranslationInObjectFrame(headIndex);
palOrbOffset = jointTranslation.y / 2;
}
thisAvatarPalData.insert("palOrbOffset", palOrbOffset);
palData.append(thisAvatarPalData);
}
++itr;
}
QJsonObject doc;
doc.insert("data", palData);
return doc.toVariantMap();
}

View file

@ -157,6 +157,17 @@ public:
*/ */
Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value); Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value);
/**jsdoc
* Used in the PAL for getting PAL-related data about avatars nearby. Using this method is faster
* than iterating over each avatar and obtaining data about them in JavaScript, as that method
* locks and unlocks each avatar's data structure potentially hundreds of times per update tick.
* @function AvatarManager.getPalData
* @param {string[]} specificAvatarIdentifiers - A list of specific Avatar Identifiers about
* which you want to get PAL data
* @returns {object}
*/
Q_INVOKABLE QVariantMap getPalData(const QList<QString> specificAvatarIdentifiers = QList<QString>());
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); } float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
int getIdentityRequestsSent() const { return _identityRequestsSent; } int getIdentityRequestsSent() const { return _identityRequestsSent; }

View file

@ -3551,6 +3551,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) {
if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
activate(Rotation); activate(Rotation);
myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing);
} }
if (myAvatar.getCenterOfGravityModelEnabled()) { if (myAvatar.getCenterOfGravityModelEnabled()) {
if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) {
@ -3568,6 +3569,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
} else { } else {
if (!isActive(Rotation) && getForceActivateRotation()) { if (!isActive(Rotation) && getForceActivateRotation()) {
activate(Rotation); activate(Rotation);
myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing);
setForceActivateRotation(false); setForceActivateRotation(false);
} }
if (!isActive(Horizontal) && getForceActivateHorizontal()) { if (!isActive(Horizontal) && getForceActivateHorizontal()) {

View file

@ -883,6 +883,7 @@ public:
virtual void rebuildCollisionShape() override; virtual void rebuildCollisionShape() override;
const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; } const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; }
void setHeadControllerFacingMovingAverage(glm::vec2 currentHeadControllerFacing) { _headControllerFacingMovingAverage = currentHeadControllerFacing; }
float getCurrentStandingHeight() const { return _currentStandingHeight; } float getCurrentStandingHeight() const { return _currentStandingHeight; }
void setCurrentStandingHeight(float newMode) { _currentStandingHeight = newMode; } void setCurrentStandingHeight(float newMode) { _currentStandingHeight = newMode; }
const glm::quat getAverageHeadRotation() const { return _averageHeadRotation; } const glm::quat getAverageHeadRotation() const { return _averageHeadRotation; }

View file

@ -381,7 +381,7 @@ public slots:
/**jsdoc /**jsdoc
* Get the rotation of the left palm in world coordinates. * Get the rotation of the left palm in world coordinates.
* @function MyAvatar.getLeftPalmRotation * @function MyAvatar.getLeftPalmRotation
* @returns {Vec3} The rotation of the left palm in world coordinates. * @returns {Quat} The rotation of the left palm in world coordinates.
* @example <caption>Report the rotation of your avatar's left palm.</caption> * @example <caption>Report the rotation of your avatar's left palm.</caption>
* print(JSON.stringify(MyAvatar.getLeftPalmRotation())); * print(JSON.stringify(MyAvatar.getLeftPalmRotation()));
*/ */
@ -398,7 +398,7 @@ public slots:
/**jsdoc /**jsdoc
* Get the rotation of the right palm in world coordinates. * Get the rotation of the right palm in world coordinates.
* @function MyAvatar.getRightPalmRotation * @function MyAvatar.getRightPalmRotation
* @returns {Vec3} The rotation of the right palm in world coordinates. * @returns {Quat} The rotation of the right palm in world coordinates.
* @example <caption>Report the rotation of your avatar's right palm.</caption> * @example <caption>Report the rotation of your avatar's right palm.</caption>
* print(JSON.stringify(MyAvatar.getRightPalmRotation())); * print(JSON.stringify(MyAvatar.getRightPalmRotation()));
*/ */

View file

@ -363,12 +363,18 @@ bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity
return false; return false;
} }
void EntityRenderer::updateModelTransform() { void EntityRenderer::updateModelTransformAndBound() {
bool success = false; bool success = false;
auto newModelTransform = _entity->getTransformToCenter(success); auto newModelTransform = _entity->getTransformToCenter(success);
if (success) { if (success) {
_modelTransform = newModelTransform; _modelTransform = newModelTransform;
} }
success = false;
auto bound = _entity->getAABox(success);
if (success) {
_bound = bound;
}
} }
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) {
@ -380,15 +386,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
} }
_prevIsTransparent = transparent; _prevIsTransparent = transparent;
bool success = false; updateModelTransformAndBound();
auto bound = entity->getAABox(success);
if (success) {
_bound = bound;
}
auto newModelTransform = entity->getTransformToCenter(success);
if (success) {
_modelTransform = newModelTransform;
}
_moving = entity->isMovingRelativeToParent(); _moving = entity->isMovingRelativeToParent();
_visible = entity->getVisible(); _visible = entity->getVisible();

View file

@ -97,7 +97,7 @@ protected:
virtual void doRender(RenderArgs* args) = 0; virtual void doRender(RenderArgs* args) = 0;
bool isFading() const { return _isFading; } bool isFading() const { return _isFading; }
void updateModelTransform(); void updateModelTransformAndBound();
virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; } virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; }
inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; } inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; }

View file

@ -126,7 +126,7 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
void* key = (void*)this; void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] () { AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] () {
withWriteLock([&] { withWriteLock([&] {
updateModelTransform(); updateModelTransformAndBound();
_renderTransform = getModelTransform(); _renderTransform = getModelTransform();
}); });
}); });

View file

@ -106,10 +106,8 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
_position = entity->getWorldPosition(); _position = entity->getWorldPosition();
_dimensions = entity->getScaledDimensions(); _dimensions = entity->getScaledDimensions();
_orientation = entity->getWorldOrientation(); _orientation = entity->getWorldOrientation();
bool success = false; updateModelTransformAndBound();
auto newModelTransform = entity->getTransformToCenter(success); _renderTransform = getModelTransform();
_renderTransform = success ? newModelTransform : getModelTransform();
if (_shape == entity::Sphere) { if (_shape == entity::Sphere) {
_renderTransform.postScale(SPHERE_ENTITY_SCALE); _renderTransform.postScale(SPHERE_ENTITY_SCALE);
} }

View file

@ -70,7 +70,7 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () { AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () {
withWriteLock([&] { withWriteLock([&] {
_dimensions = entity->getScaledDimensions(); _dimensions = entity->getScaledDimensions();
updateModelTransform(); updateModelTransformAndBound();
_renderTransform = getModelTransform(); _renderTransform = getModelTransform();
}); });
}); });

View file

@ -206,7 +206,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
glm::vec2 windowSize = getWindowSize(entity); glm::vec2 windowSize = getWindowSize(entity);
_webSurface->resize(QSize(windowSize.x, windowSize.y)); _webSurface->resize(QSize(windowSize.x, windowSize.y));
updateModelTransform(); updateModelTransformAndBound();
_renderTransform = getModelTransform(); _renderTransform = getModelTransform();
_renderTransform.postScale(entity->getScaledDimensions()); _renderTransform.postScale(entity->getScaledDimensions());
}); });

View file

@ -262,24 +262,53 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
btVector3 linearDisplacement = clampLength(vel * dt, MAX_DISPLACEMENT); // clamp displacement to prevent tunneling. btVector3 linearDisplacement = clampLength(vel * dt, MAX_DISPLACEMENT); // clamp displacement to prevent tunneling.
btVector3 endPos = startPos + linearDisplacement; btVector3 endPos = startPos + linearDisplacement;
// resolve the simple linearDisplacement
_followLinearDisplacement += linearDisplacement;
// now for the rotational part...
btQuaternion startRot = bodyTransform.getRotation(); btQuaternion startRot = bodyTransform.getRotation();
btQuaternion desiredRot = _followDesiredBodyTransform.getRotation(); btQuaternion desiredRot = _followDesiredBodyTransform.getRotation();
if (desiredRot.dot(startRot) < 0.0f) {
desiredRot = -desiredRot; // startRot as default rotation
btQuaternion endRot = startRot;
// the dot product between two quaternions is equal to +/- cos(angle/2)
// where 'angle' is that of the rotation between them
float qDot = desiredRot.dot(startRot);
// when the abs() value of the dot product is approximately 1.0
// then the two rotations are effectively adjacent
const float MIN_DOT_PRODUCT_OF_ADJACENT_QUATERNIONS = 0.99999f; // corresponds to approx 0.5 degrees
if (fabsf(qDot) < MIN_DOT_PRODUCT_OF_ADJACENT_QUATERNIONS) {
if (qDot < 0.0f) {
// the quaternions are actually on opposite hyperhemispheres
// so we move one to agree with the other and negate qDot
desiredRot = -desiredRot;
qDot = -qDot;
}
btQuaternion deltaRot = desiredRot * startRot.inverse();
// the axis is the imaginary part, but scaled by sin(angle/2)
btVector3 axis(deltaRot.getX(), deltaRot.getY(), deltaRot.getZ());
axis /= sqrtf(1.0f - qDot * qDot);
// compute the angle we will resolve for this dt, but don't overshoot
float angle = 2.0f * acosf(qDot);
if ( dt < _followTimeRemaining) {
angle *= dt / _followTimeRemaining;
}
// accumulate rotation
deltaRot = btQuaternion(axis, angle);
_followAngularDisplacement = (deltaRot * _followAngularDisplacement).normalize();
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);
endRot = deltaRot * startRot;
btVector3 swingDisplacement = rotateVector(endRot, -shapeLocalOffset) - rotateVector(startRot, -shapeLocalOffset);
_followLinearDisplacement += swingDisplacement;
} }
btQuaternion deltaRot = desiredRot * startRot.inverse();
float angularSpeed = deltaRot.getAngle() / _followTimeRemaining;
glm::vec3 rotationAxis = glm::normalize(glm::axis(bulletToGLM(deltaRot))); // deltaRot.getAxis() is inaccurate
btQuaternion angularDisplacement = btQuaternion(glmToBullet(rotationAxis), angularSpeed * dt);
btQuaternion endRot = angularDisplacement * startRot;
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);
btVector3 swingDisplacement = rotateVector(endRot, -shapeLocalOffset) - rotateVector(startRot, -shapeLocalOffset);
_followLinearDisplacement = linearDisplacement + swingDisplacement + _followLinearDisplacement;
_followAngularDisplacement = angularDisplacement * _followAngularDisplacement;
_rigidBody->setWorldTransform(btTransform(endRot, endPos)); _rigidBody->setWorldTransform(btTransform(endRot, endPos));
} }
_followTime += dt; _followTime += dt;

View file

@ -159,6 +159,9 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
for(var bookmarkName in message.data.bookmarks) { for(var bookmarkName in message.data.bookmarks) {
var bookmark = message.data.bookmarks[bookmarkName]; var bookmark = message.data.bookmarks[bookmarkName];
if (!bookmark.avatarEntites) { // ensure avatarEntites always exist
bookmark.avatarEntites = [];
}
bookmark.avatarEntites.forEach(function(avatarEntity) { bookmark.avatarEntites.forEach(function(avatarEntity) {
avatarEntity.properties.localRotationAngles = Quat.safeEulerAngles(avatarEntity.properties.localRotation) avatarEntity.properties.localRotationAngles = Quat.safeEulerAngles(avatarEntity.properties.localRotation)

View file

@ -11,7 +11,8 @@
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME,
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity,
distanceBetweenEntityLocalPositionAndBoundingBox
*/ */
Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -172,12 +173,9 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * TEAR_AWAY_CHECK_TIME) { if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * TEAR_AWAY_CHECK_TIME) {
this.lastUnequipCheckTime = now; this.lastUnequipCheckTime = now;
if (props.parentID === MyAvatar.SELF_ID) { if (props.parentID === MyAvatar.SELF_ID) {
var sensorScaleFactor = MyAvatar.sensorToWorldScale; var tearAwayDistance = TEAR_AWAY_DISTANCE * MyAvatar.sensorToWorldScale;
var handPosition = controllerData.controllerLocations[this.hand].position; var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props);
var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props); if (distance > tearAwayDistance) {
var distance = Vec3.distance(props.position, handPosition);
if ((dist > TEAR_AWAY_DISTANCE) ||
(distance > NEAR_GRAB_RADIUS * sensorScaleFactor)) {
this.autoUnequipCounter++; this.autoUnequipCounter++;
} else { } else {
this.autoUnequipCounter = 0; this.autoUnequipCounter = 0;

View file

@ -1573,15 +1573,11 @@ function deleteSelectedEntities() {
Entities.deleteEntity(entityID); Entities.deleteEntity(entityID);
} }
} }
if (savedProperties.length > 0) { if (savedProperties.length > 0) {
SelectionManager.clearSelections(); SelectionManager.clearSelections();
pushCommandForSelections([], savedProperties); pushCommandForSelections([], savedProperties);
entityListTool.deleteEntities(deletedIDs);
entityListTool.webView.emitScriptEvent(JSON.stringify({
type: "deleted",
ids: deletedIDs
}));
} }
} }
} }
@ -1853,13 +1849,7 @@ var keyReleaseEvent = function (event) {
} }
} else if (event.text === 'g') { } else if (event.text === 'g') {
if (isActive && selectionManager.hasSelection()) { if (isActive && selectionManager.hasSelection()) {
var newPosition = selectionManager.worldPosition; grid.moveToSelection();
newPosition = Vec3.subtract(newPosition, {
x: 0,
y: selectionManager.worldDimensions.y * 0.5,
z: 0
});
grid.setPosition(newPosition);
} }
} else if (event.key === KEY_P && event.isControl && !event.isAutoRepeat ) { } else if (event.key === KEY_P && event.isControl && !event.isAutoRepeat ) {
if (event.isShifted) { if (event.isShifted) {

View file

@ -59,6 +59,7 @@
highlightTargetEntity:true, highlightTargetEntity:true,
clearHighlightedEntities:true, clearHighlightedEntities:true,
unhighlightTargetEntity:true unhighlightTargetEntity:true
distanceBetweenEntityLocalPositionAndBoundingBox: true
*/ */
MSECS_PER_SEC = 1000.0; MSECS_PER_SEC = 1000.0;
@ -130,7 +131,9 @@ DISPATCHER_PROPERTIES = [
"type", "type",
"href", "href",
"cloneable", "cloneable",
"cloneDynamic" "cloneDynamic",
"localPosition",
"localRotation"
]; ];
// priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step // priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step
@ -413,6 +416,25 @@ findHandChildEntities = function(hand) {
}); });
}; };
distanceBetweenEntityLocalPositionAndBoundingBox = function(entityProps) {
var localPoint = entityProps.localPosition;
var entityXform = new Xform(entityProps.rotation, entityProps.position);
var minOffset = Vec3.multiplyVbyV(entityProps.registrationPoint, entityProps.dimensions);
var maxOffset = Vec3.multiplyVbyV(Vec3.subtract(ONE_VEC, entityProps.registrationPoint), entityProps.dimensions);
var localMin = Vec3.subtract(entityXform.trans, minOffset);
var localMax = Vec3.sum(entityXform.trans, maxOffset);
var v = {x: localPoint.x, y: localPoint.y, z: localPoint.z};
v.x = Math.max(v.x, localMin.x);
v.x = Math.min(v.x, localMax.x);
v.y = Math.max(v.y, localMin.y);
v.y = Math.min(v.y, localMax.y);
v.z = Math.max(v.z, localMin.z);
v.z = Math.min(v.z, localMax.z);
return Vec3.distance(v, localPoint);
};
distanceBetweenPointAndEntityBoundingBox = function(point, entityProps) { distanceBetweenPointAndEntityBoundingBox = function(point, entityProps) {
var entityXform = new Xform(entityProps.rotation, entityProps.position); var entityXform = new Xform(entityProps.rotation, entityProps.position);
var localPoint = entityXform.inv().xformPoint(point); var localPoint = entityXform.inv().xformPoint(point);

View file

@ -93,12 +93,18 @@ EntityListTool = function() {
}; };
that.removeEntities = function (deletedIDs, selectedIDs) { that.removeEntities = function (deletedIDs, selectedIDs) {
var data = { emitJSONScriptEvent({
type: 'removeEntities', type: 'removeEntities',
deletedIDs: deletedIDs, deletedIDs: deletedIDs,
selectedIDs: selectedIDs selectedIDs: selectedIDs
}; });
webView.emitScriptEvent(JSON.stringify(data)); };
that.deleteEntities = function (deletedIDs) {
emitJSONScriptEvent({
type: "deleted",
ids: deletedIDs
});
}; };
function valueIfDefined(value) { function valueIfDefined(value) {

View file

@ -1186,10 +1186,17 @@ SelectionDisplay = (function() {
var localRotationZ = Quat.fromPitchYawRollDegrees(rotationDegrees, 0, 0); var localRotationZ = Quat.fromPitchYawRollDegrees(rotationDegrees, 0, 0);
var rotationZ = Quat.multiply(rotation, localRotationZ); var rotationZ = Quat.multiply(rotation, localRotationZ);
worldRotationZ = rotationZ; worldRotationZ = rotationZ;
var selectionBoxGeometry = {
position: position,
rotation: rotation,
dimensions: dimensions
};
var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry);
// in HMD we clamp the overlays to the bounding box for now so lasers can hit them // in HMD if outside the bounding box clamp the overlays to the bounding box for now so lasers can hit them
var maxHandleDimension = 0; var maxHandleDimension = 0;
if (HMD.active) { if (HMD.active && !isCameraInsideBox) {
maxHandleDimension = Math.max(dimensions.x, dimensions.y, dimensions.z); maxHandleDimension = Math.max(dimensions.x, dimensions.y, dimensions.z);
} }
@ -1438,12 +1445,6 @@ SelectionDisplay = (function() {
var inModeRotate = isActiveTool(handleRotatePitchRing) || var inModeRotate = isActiveTool(handleRotatePitchRing) ||
isActiveTool(handleRotateYawRing) || isActiveTool(handleRotateYawRing) ||
isActiveTool(handleRotateRollRing); isActiveTool(handleRotateRollRing);
var selectionBoxGeometry = {
position: position,
rotation: rotation,
dimensions: dimensions
};
var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry);
selectionBoxGeometry.visible = !inModeRotate && !isCameraInsideBox; selectionBoxGeometry.visible = !inModeRotate && !isCameraInsideBox;
Overlays.editOverlay(selectionBox, selectionBoxGeometry); Overlays.editOverlay(selectionBox, selectionBoxGeometry);

View file

@ -154,6 +154,12 @@ Grid = function(opts) {
that.emitUpdate(); that.emitUpdate();
} }
}; };
that.moveToSelection = function() {
var newPosition = SelectionManager.worldPosition;
newPosition = Vec3.subtract(newPosition, { x: 0, y: SelectionManager.worldDimensions.y * 0.5, z: 0 });
that.setPosition(newPosition);
};
that.emitUpdate = function() { that.emitUpdate = function() {
if (that.onUpdate) { if (that.onUpdate) {
@ -280,9 +286,7 @@ GridTool = function(opts) {
} }
horizontalGrid.setPosition(position); horizontalGrid.setPosition(position);
} else if (action == "moveToSelection") { } else if (action == "moveToSelection") {
var newPosition = selectionManager.worldPosition; horizontalGrid.moveToSelection();
newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 });
grid.setPosition(newPosition);
} }
} }
}; };

View file

@ -19,7 +19,7 @@
var populateNearbyUserList, color, textures, removeOverlays, var populateNearbyUserList, color, textures, removeOverlays,
controllerComputePickRay, onTabletButtonClicked, onTabletScreenChanged, controllerComputePickRay, onTabletButtonClicked, onTabletScreenChanged,
receiveMessage, avatarDisconnected, clearLocalQMLDataAndClosePAL, receiveMessage, avatarDisconnected, clearLocalQMLDataAndClosePAL,
createAudioInterval, tablet, CHANNEL, getConnectionData, findableByChanged, tablet, CHANNEL, getConnectionData, findableByChanged,
avatarAdded, avatarRemoved, avatarSessionChanged; // forward references; avatarAdded, avatarRemoved, avatarSessionChanged; // forward references;
// hardcoding these as it appears we cannot traverse the originalTextures in overlays??? Maybe I've missed // hardcoding these as it appears we cannot traverse the originalTextures in overlays??? Maybe I've missed
@ -447,21 +447,24 @@ function populateNearbyUserList(selectData, oldAudioData) {
verticalAngleNormal = filter && Quat.getRight(orientation), verticalAngleNormal = filter && Quat.getRight(orientation),
horizontalAngleNormal = filter && Quat.getUp(orientation); horizontalAngleNormal = filter && Quat.getUp(orientation);
avatarsOfInterest = {}; avatarsOfInterest = {};
avatars.forEach(function (id) {
var avatar = AvatarList.getAvatar(id); var avatarData = AvatarList.getPalData().data;
var name = avatar.sessionDisplayName;
avatarData.forEach(function (currentAvatarData) {
var id = currentAvatarData.sessionUUID;
var name = currentAvatarData.sessionDisplayName;
if (!name) { if (!name) {
// Either we got a data packet but no identity yet, or something is really messed up. In any case, // Either we got a data packet but no identity yet, or something is really messed up. In any case,
// we won't be able to do anything with this user, so don't include them. // we won't be able to do anything with this user, so don't include them.
// In normal circumstances, a refresh will bring in the new user, but if we're very heavily loaded, // In normal circumstances, a refresh will bring in the new user, but if we're very heavily loaded,
// we could be losing and gaining people randomly. // we could be losing and gaining people randomly.
print('No avatar identity data for', id); print('No avatar identity data for', currentAvatarData.sessionUUID);
return; return;
} }
if (id && myPosition && (Vec3.distance(avatar.position, myPosition) > filter.distance)) { if (id && myPosition && (Vec3.distance(currentAvatarData.position, myPosition) > filter.distance)) {
return; return;
} }
var normal = id && filter && Vec3.normalize(Vec3.subtract(avatar.position, myPosition)); var normal = id && filter && Vec3.normalize(Vec3.subtract(currentAvatarData.position, myPosition));
var horizontal = normal && angleBetweenVectorsInPlane(normal, forward, horizontalAngleNormal); var horizontal = normal && angleBetweenVectorsInPlane(normal, forward, horizontalAngleNormal);
var vertical = normal && angleBetweenVectorsInPlane(normal, forward, verticalAngleNormal); var vertical = normal && angleBetweenVectorsInPlane(normal, forward, verticalAngleNormal);
if (id && filter && ((Math.abs(horizontal) > horizontalHalfAngle) || (Math.abs(vertical) > verticalHalfAngle))) { if (id && filter && ((Math.abs(horizontal) > horizontalHalfAngle) || (Math.abs(vertical) > verticalHalfAngle))) {
@ -480,11 +483,11 @@ function populateNearbyUserList(selectData, oldAudioData) {
personalMute: !!id && Users.getPersonalMuteStatus(id), // expects proper boolean, not null personalMute: !!id && Users.getPersonalMuteStatus(id), // expects proper boolean, not null
ignore: !!id && Users.getIgnoreStatus(id), // ditto ignore: !!id && Users.getIgnoreStatus(id), // ditto
isPresent: true, isPresent: true,
isReplicated: avatar.isReplicated isReplicated: currentAvatarData.isReplicated
}; };
// Everyone needs to see admin status. Username and fingerprint returns default constructor output if the requesting user isn't an admin. // Everyone needs to see admin status. Username and fingerprint returns default constructor output if the requesting user isn't an admin.
Users.requestUsernameFromID(id); Users.requestUsernameFromID(id);
if (id) { if (id !== "") {
addAvatarNode(id); // No overlay for ourselves addAvatarNode(id); // No overlay for ourselves
avatarsOfInterest[id] = true; avatarsOfInterest[id] = true;
} else { } else {
@ -515,30 +518,63 @@ function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
updateUser(data); updateUser(data);
} }
function updateAudioLevel(avatarData) {
// the VU meter should work similarly to the one in AvatarInputs: log scale, exponentially averaged
// But of course it gets the data at a different rate, so we tweak the averaging ratio and frequency
// of updating (the latter for efficiency too).
var audioLevel = 0.0;
var avgAudioLevel = 0.0;
var data = avatarData.sessionUUID === "" ? myData : ExtendedOverlay.get(avatarData.sessionUUID);
if (data) {
// we will do exponential moving average by taking some the last loudness and averaging
data.accumulatedLevel = AVERAGING_RATIO * (data.accumulatedLevel || 0) + (1 - AVERAGING_RATIO) * (avatarData.audioLoudness);
// add 1 to insure we don't go log() and hit -infinity. Math.log is
// natural log, so to get log base 2, just divide by ln(2).
audioLevel = scaleAudio(Math.log(data.accumulatedLevel + 1) / LOG2);
// decay avgAudioLevel
avgAudioLevel = Math.max((1 - AUDIO_PEAK_DECAY) * (data.avgAudioLevel || 0), audioLevel);
data.avgAudioLevel = avgAudioLevel;
data.audioLevel = audioLevel;
// now scale for the gain. Also, asked to boost the low end, so one simple way is
// to take sqrt of the value. Lets try that, see how it feels.
avgAudioLevel = Math.min(1.0, Math.sqrt(avgAudioLevel * (sessionGains[avatarData.sessionUUID] || 0.75)));
}
var param = {};
var level = [audioLevel, avgAudioLevel];
var userId = avatarData.sessionUUID;
param[userId] = level;
sendToQml({ method: 'updateAudioLevel', params: param });
}
var pingPong = true; var pingPong = true;
function updateOverlays() { function updateOverlays() {
var eye = Camera.position; var eye = Camera.position;
AvatarList.getAvatarIdentifiers().forEach(function (id) {
if (!id || !avatarsOfInterest[id]) { var avatarData = AvatarList.getPalData().data;
avatarData.forEach(function (currentAvatarData) {
if (currentAvatarData.sessionUUID === "" || !avatarsOfInterest[currentAvatarData.sessionUUID]) {
return; // don't update ourself, or avatars we're not interested in return; // don't update ourself, or avatars we're not interested in
} }
var avatar = AvatarList.getAvatar(id); updateAudioLevel(currentAvatarData);
if (!avatar) { var overlay = ExtendedOverlay.get(currentAvatarData.sessionUUID);
return; // will be deleted below if there had been an overlay.
}
var overlay = ExtendedOverlay.get(id);
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back. if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
print('Adding non-PAL avatar node', id); print('Adding non-PAL avatar node', currentAvatarData.sessionUUID);
overlay = addAvatarNode(id); overlay = addAvatarNode(currentAvatarData.sessionUUID);
} }
var target = avatar.position;
var target = currentAvatarData.position;
var distance = Vec3.distance(target, eye); var distance = Vec3.distance(target, eye);
var offset = 0.2; var offset = currentAvatarData.palOrbOffset;
var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position) var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position)
var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can
if (headIndex > 0) {
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
}
// move a bit in front, towards the camera // move a bit in front, towards the camera
target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset)); target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset));
@ -548,7 +584,7 @@ function updateOverlays() {
overlay.ping = pingPong; overlay.ping = pingPong;
overlay.editOverlay({ overlay.editOverlay({
color: color(ExtendedOverlay.isSelected(id), overlay.hovering, overlay.audioLevel), color: color(ExtendedOverlay.isSelected(currentAvatarData.sessionUUID), overlay.hovering, overlay.audioLevel),
position: target, position: target,
dimensions: 0.032 * distance dimensions: 0.032 * distance
}); });
@ -704,6 +740,13 @@ function wireEventBridge(on) {
hasEventBridge = false; hasEventBridge = false;
} }
} }
}
var UPDATE_INTERVAL_MS = 100;
function createUpdateInterval() {
return Script.setInterval(function () {
updateOverlays();
}, UPDATE_INTERVAL_MS);
} }
function onTabletScreenChanged(type, url) { function onTabletScreenChanged(type, url) {
@ -719,10 +762,8 @@ function onTabletScreenChanged(type, url) {
ContextOverlay.enabled = false; ContextOverlay.enabled = false;
Users.requestsDomainListData = true; Users.requestsDomainListData = true;
audioTimer = createAudioInterval(AUDIO_LEVEL_UPDATE_INTERVAL_MS);
tablet.tabletShownChanged.connect(tabletVisibilityChanged); tablet.tabletShownChanged.connect(tabletVisibilityChanged);
Script.update.connect(updateOverlays); updateInterval = createUpdateInterval();
Controller.mousePressEvent.connect(handleMouseEvent); Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent); Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
Users.usernameFromIDReply.connect(usernameFromIDReply); Users.usernameFromIDReply.connect(usernameFromIDReply);
@ -778,50 +819,6 @@ function scaleAudio(val) {
return audioLevel; return audioLevel;
} }
function getAudioLevel(id) {
// the VU meter should work similarly to the one in AvatarInputs: log scale, exponentially averaged
// But of course it gets the data at a different rate, so we tweak the averaging ratio and frequency
// of updating (the latter for efficiency too).
var avatar = AvatarList.getAvatar(id);
var audioLevel = 0.0;
var avgAudioLevel = 0.0;
var data = id ? ExtendedOverlay.get(id) : myData;
if (data) {
// we will do exponential moving average by taking some the last loudness and averaging
data.accumulatedLevel = AVERAGING_RATIO * (data.accumulatedLevel || 0) + (1 - AVERAGING_RATIO) * (avatar.audioLoudness);
// add 1 to insure we don't go log() and hit -infinity. Math.log is
// natural log, so to get log base 2, just divide by ln(2).
audioLevel = scaleAudio(Math.log(data.accumulatedLevel + 1) / LOG2);
// decay avgAudioLevel
avgAudioLevel = Math.max((1 - AUDIO_PEAK_DECAY) * (data.avgAudioLevel || 0), audioLevel);
data.avgAudioLevel = avgAudioLevel;
data.audioLevel = audioLevel;
// now scale for the gain. Also, asked to boost the low end, so one simple way is
// to take sqrt of the value. Lets try that, see how it feels.
avgAudioLevel = Math.min(1.0, Math.sqrt(avgAudioLevel * (sessionGains[id] || 0.75)));
}
return [audioLevel, avgAudioLevel];
}
function createAudioInterval(interval) {
// we will update the audioLevels periodically
// TODO: tune for efficiency - expecially with large numbers of avatars
return Script.setInterval(function () {
var param = {};
AvatarList.getAvatarIdentifiers().forEach(function (id) {
var level = getAudioLevel(id),
userId = id || 0; // qml didn't like an object with null/empty string for a key, so...
param[userId] = level;
});
sendToQml({method: 'updateAudioLevel', params: param});
}, interval);
}
function avatarDisconnected(nodeID) { function avatarDisconnected(nodeID) {
// remove from the pal list // remove from the pal list
sendToQml({method: 'avatarDisconnected', params: [nodeID]}); sendToQml({method: 'avatarDisconnected', params: [nodeID]});
@ -874,11 +871,11 @@ startup();
var isWired = false; var isWired = false;
var audioTimer;
var AUDIO_LEVEL_UPDATE_INTERVAL_MS = 100; // 10hz for now (change this and change the AVERAGING_RATIO too)
function off() { function off() {
if (isWired) { if (isWired) {
Script.update.disconnect(updateOverlays); if (updateInterval) {
Script.clearInterval(updateInterval);
}
Controller.mousePressEvent.disconnect(handleMouseEvent); Controller.mousePressEvent.disconnect(handleMouseEvent);
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
tablet.tabletShownChanged.disconnect(tabletVisibilityChanged); tablet.tabletShownChanged.disconnect(tabletVisibilityChanged);
@ -889,10 +886,6 @@ function off() {
Users.requestsDomainListData = false; Users.requestsDomainListData = false;
isWired = false; isWired = false;
if (audioTimer) {
Script.clearInterval(audioTimer);
}
} }
removeOverlays(); removeOverlays();

View file

@ -31,8 +31,8 @@ BakerCLI::BakerCLI(OvenCLIApplication* parent) : QObject(parent) {
void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) { void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) {
// if the URL doesn't have a scheme, assume it is a local file // if the URL doesn't have a scheme, assume it is a local file
if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp") { if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp" && inputUrl.scheme() != "file") {
inputUrl.setScheme("file"); inputUrl = QUrl::fromLocalFile(inputUrl.toString());
} }
qDebug() << "Baking file type: " << type; qDebug() << "Baking file type: " << type;